доброго времени суток, собираю термометр на базе плат от часов алекса гайвера v2, собрал из кусков код, все компилируется, в нано заливается, а вот цифры загораются на секунду и тухнут. В программировании я полный О, пните плиз в нужном направлении.
#define THERMOSENSOR 2 //DS18B20 data
// 74141 кд155ид1 выходы
#define BCDA A3
#define BCDB A1
#define BCDC A0
#define BCDD A2
// оптопары, транзисторы выходы
#define NIXIE1 4 // 1 лампа
#define NIXIE2 5 // 2 лампа
#define NIXIE3 6 // 3 лампа
#define GEN 9 // генератор
#define SLOT_MACHINE_EFFECT true // Enable slot-machine effect for anti-cathode poisoning
#define BURN_TIME 50
#define BURN_PERIOD 600
// Variables for timing
unsigned long t = 0;
unsigned long t_prev = 0;
int updateInterval = 10000; //ms
OneWire oneWire(THERMOSENSOR);
DallasTemperature sensors(&oneWire);
/*
1) читать температуру => плавать
2) преобразовать его в int (21,3700005 => 214)
3) разделить его на байт[]: 2,1,4
4) конвертировать в двоично-десятичный код 2 => 0010
5) показывать
*/
void setup() {
Serial.println("start");
sensors.begin();
Serial.begin(9600);
pinMode(BCDA, OUTPUT);
pinMode(BCDB, OUTPUT);
pinMode(BCDC, OUTPUT);
pinMode(BCDD, OUTPUT);
pinMode(NIXIE1, OUTPUT);
pinMode(NIXIE2, OUTPUT);
pinMode(NIXIE2, OUTPUT);
pinMode(GEN, OUTPUT);
// задаем частоту ШИМ на 9 и 10 выводах 31 кГц
TCCR1B = TCCR1B & 0b11111000 | 1; // ставим делитель 1
// включаем ШИМ
// от скважности зависит напряжение! у 175 вольт при значении 180 и 145 вольт при 120
setPWM(9, 180);
// перенастраиваем частоту ШИМ на пинах 3 и 11 на 7.8 кГц и разрешаем прерывания по совпадению
TCCR2B = (TCCR2B & B11111000) | 2; // делитель 8
TCCR2A |= (1 << WGM21); // включить CTC режим для COMPA
TIMSK2 |= (1 << OCIE2A); // включить прерывания по совпадению COMPA
}
void toggleNixies(bool n1, bool n2, bool n3) {
toggleSingleNixie(NIXIE1, n1);
toggleSingleNixie(NIXIE2, n2);
toggleSingleNixie(NIXIE3, n3);
}
// включить/выключить указанную трубку
void toggleSingleNixie( int nid, bool on) {
digitalWrite(nid, uint8_t(on));
}
// преобразовать плавающую температуру в int - 21.580009 => 216 для отображения на 3 Nixies
int floatToDisplayValue(float f) {
if(f>99.9){
return 999; //невозможно отобразить большее значение
}
f=f*10;
return round(f);
}
float requestTemperature() {
sensors.setWaitForConversion(false); // делает это асинхронным
sensors.requestTemperatures();
sensors.setWaitForConversion(true);
}
// преобразовать один байт в массив из 4 бит 1 => byte[3]{1,2,3}
void intToBcdArray(byte val, int* bcdArray, int size) {
byte bcd = ((val / 10) << 4) | (val % 10);
for (int i = 0; i < size; i++) {
bcdArray[i] = (bcd >> i) & 1;
}
}
void displayNum(int* bcd) {
digitalWrite(BCDA, bcd[0]);
digitalWrite(BCDB, bcd[1]);
digitalWrite(BCDC, bcd[2]);
digitalWrite(BCDD, bcd[3]);
}
//отображать номер на 1-й (наиболее значимой) трубке
void display1(byte dig) {
// если dig == 0, не показывать
if(dig == 0) {return;}
toggleNixies(true, false, false);
int bcdArray[4];
intToBcdArray(dig, bcdArray, 4);
displayNum(bcdArray);
}
//номер дисплея на второй трубке
void display2(byte dig) {
// если dig == 0, не показывать
toggleNixies(false, true, false);
int bcdArray[4];
intToBcdArray(dig, bcdArray, 4);
displayNum(bcdArray);
}
// отображаемый номер на третьей трубке - десятичныйl
void display3(byte dig) {
// если dig == 0, не показывать
toggleNixies(false, false, true);
int bcdArray[4];
intToBcdArray(dig, bcdArray, 4);
displayNum(bcdArray);
}
void display(int num) {
byte digits[3];
numToDecs(num, digits, 3);
display1(digits[0]);
delay(5);
display2(digits[1]);
delay(5);
display3(digits[2]);
delay(5);
}
// преобразовать число в массив десятичных байтов int 123 => byte[1,2,3]
void numToDecs(int num, byte* decs, int len) {
int i = len;
int div = 0;
while(i>0) {
div = pow(10, i-1)+0.5; // pow работает с двойными числами, приведение float к int удаляет только десятичные дроби (10**2 => 99,9 => (int)99 ), поэтому мы добавляем 0,5, чтобы убедиться, что это правильно.
decs[len-i]=num/div;
num = num % div;
i--;
}
}
int dv = 666; // Начальное значение
float temp=0;
void loop() {
//запросить температуру
requestTemperature();
byte digits[3];
for(uint32_t start = millis(); (millis()-start <updateInterval);) {
if(millis() - start >750 && millis() - start <770 ){
temp=sensors.getTempCByIndex(0);
dv = floatToDisplayValue(temp);
}
display(dv);
}
#if (SLOT_MACHINE_EFFECT)
t = millis();
if (t - t_prev > BURN_PERIOD) { // Do slot-machine effect every 60 seconds
t_prev = t;
for (byte i = 0; i < 10; i++) {
digits[0] = i;
digits[1] = i;
digits[2] = i;
delay(BURN_TIME);
}
}
#endif
}