Использую 7seg 3 digit BA56-12GWA интересует способы его подключения
- Войдите на сайт для отправки комментариев
Чт, 05/02/2015 - 13:39
1. Это через один 74HC595 (так он у меня сейчас работает) и три пина(у индикатора всего 12 ног) (динамический)
есть проблема, что с терморезистора даются чувствительные данные и меня раздражает, что плавает десятая доля температуры. Выглядит так как буд-то горят все сегменты, но когда "устаканилась" температура всё хорошо вроде бы:)
Думаю попробовать средними значениями помочь - но кажется не поможет.
Возможно другой способ подключения посоветуете? Два 74HC595?
А уменьшить частоту вывода данных?
При динамической индикации обычно один разряд индикатора отображается порядка 5 мс (если дольше то будет мерцание). Т.е. три цифры отобразятся за 15 мс и если на каждом таком цикле значение изменяется то и будет видимость что горят все сегменты. А правильно надо делать как то так:
value = // значение температуры unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { DisplayNumber(value); }Т.е. 0,5 сек будет отображаться одно значение. Время можно подобрать в зависимости от желаемой динамики.
Господа, объясните вы мне, где происходят такие процессы, которые нуждаются в визуальном контроле температуры каждые 0,5 секунды и чаще???? От для меня это загадка.
При динамической индикации обычно один разряд индикатора отображается порядка 5 мс (если дольше то будет мерцание). Т.е. три цифры отобразятся за 15 мс и если на каждом таком цикле значение изменяется то и будет видимость что горят все сегменты. А правильно надо делать как то так:
value = // значение температуры unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { DisplayNumber(value); }Т.е. 0,5 сек будет отображаться одно значение. Время можно подобрать в зависимости от желаемой динамики.
Подчистил скетч от ненужного, не совсем понимаю, где эта задержка будет находиться?
#include <math.h> // DS отвечает за поток битов(данные). На Схеме 595 пин 14 #define DATA_PIN 4 //STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12 #define LATCH_PIN 3 // SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11 #define CLOCK_PIN 2 const int digitPins[3] = { 52,51,50}; //Массив пинов. Выбрал произвольные кониакты у меня Мега int8_t Disp[3]={ 0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало. int Value; int i = 0; #define ledPin1 22 #define ledPin2 23 double TempRes; // Температура с терморезистора byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; void setup() { Serial.begin(115200); pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } void printInd1() { for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, B11111111); digitalWrite(LATCH_PIN, HIGH); delayMicroseconds(100); digitalWrite(digitPins[i], HIGH); digitalWrite(LATCH_PIN, LOW); if(i==1){ shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, ~(segments[Disp[i]] | B10000000));//print the decimal point on the 3rd digit } else shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, ~segments[Disp[i]]); digitalWrite(LATCH_PIN, HIGH); i++; if(i > 2) i=0; } double Steinhart (int value) { double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double B = 3988.0; // Параметр конкретного типа термистора (из datasheet) TempRes = (1.0 / (1.0 / (B)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; // 10KOm - R_25 Value=TempRes *10; //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //десятки Disp[1] = (Value/10)%10;//единицы Disp[2] = Value%10; //десятые //Функция для отображения на индикаторе printInd1(); return TempRes; } void loop() { Steinhart(analogRead(1)); }http://youtu.be/gque6VXJlFY
вот записал как это происходит, лучше не получилось:(
Подчистил скетч от ненужного, не совсем понимаю, где эта задержка будет находиться?
double Steinhart (int value) { double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double B = 3988.0; // Параметр конкретного типа термистора (из datasheet) TempRes = (1.0 / (1.0 / (B)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; // 10KOm - R_25 Value=TempRes *10; //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //десятки Disp[1] = (Value/10)%10;//единицы Disp[2] = Value%10; //десятые //Функция для отображения на индикаторе unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { printInd1(); } return TempRes; }Как-то так должно быть.
Вот только не понял куда возвращает эта функция значение
TempRes?Вот только не понял куда возвращает эта функция значение
TempRes?там дальше используется для сравнения, убрал лишний код;)
Подчистил скетч от ненужного, не совсем понимаю, где эта задержка будет находиться?
double Steinhart (int value) { double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double B = 3988.0; // Параметр конкретного типа термистора (из datasheet) TempRes = (1.0 / (1.0 / (B)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; // 10KOm - R_25 Value=TempRes *10; //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //десятки Disp[1] = (Value/10)%10;//единицы Disp[2] = Value%10; //десятые //Функция для отображения на индикаторе unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { printInd1(); } return TempRes; }Как-то так должно быть.
Вот только не понял куда возвращает эта функция значение
TempRes?очень сильно упала яркость, через нпн транзисторы подключить?
Может слишком быстро или слишком медленно на 595-ю данные гонятся?
Зачем вообще 74HC595 если индикатор всего 3-разрядный и аж целая Мега используется? 11 цифровых пинов жалко? Мне на 4-разрядный хватало Про Мини + 4 транзистора на общие аноды/катоды.
Может слишком быстро или слишком медленно на 595-ю данные гонятся?
Зачем вообще 74HC595 если индикатор всего 3-разрядный и аж целая Мега используется? 11 цифровых пинов жалко? Мне на 4-разрядный хватало Про Мини + 4 транзистора на общие аноды/катоды.
Целевая будет ATTINY 84, а у неё всего 14 ног.
Подключение вот такое... как на схеме
Нормальная вроде схема. Я в программе не увидел задания делителя частоты для SPI поэтому shiftOut() может выполняться с тактовой до 4МГц. А в функции PrintInd1() есть несоответствие схеме и вообще вроде накосячено. В общем цикле перебираются разряды, при этом на выбранный пин выводится низкий уровень, а по схеме должен высокий. Для каждого разряда зачем-то выводятся сегменты от всех трех цифр. Плюс задержка на 100 мкс при погашенном индикаторе (в 595-ю задвинуты все единицы) а после того как задвигается выводимая цифра задержки нет, сразу переход к следующей. Т.е. в каждый разряд выводятся с большой частотой три цифры с паузой 100 мкс между разрядами. Время когда светятся сегменты значительно меньше паузы. Поэтому и яркость маленькая. А из-за того что в каждом разряде по три цифры одновременно все сегменты и горят.
Нормальная вроде схема. Я в программе не увидел задания делителя частоты для SPI поэтому shiftOut() может выполняться с тактовой до 4МГц. А в функции PrintInd1() есть несоответствие схеме и вообще вроде накосячено. В общем цикле перебираются разряды, при этом на выбранный пин выводится низкий уровень, а по схеме должен высокий. Для каждого разряда зачем-то выводятся сегменты от всех трех цифр. Плюс задержка на 100 мкс при погашенном индикаторе (в 595-ю задвинуты все единицы) а после того как задвигается выводимая цифра задержки нет, сразу переход к следующей. Т.е. в каждый разряд выводятся с большой частотой три цифры с паузой 100 мкс между разрядами. Время когда светятся сегменты значительно меньше паузы. Поэтому и яркость маленькая. А из-за того что в каждом разряде по три цифры одновременно все сегменты и горят.
http://www.instructables.com/id/Temperature-Displayed-on-4-Digit-7-segment-common/
делал по вот этому примеру
Нужно использовать http://arduino.ru/Reference/Library/SPI ?
Вся яркость пропадает если добавить строки
unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { printInd1(); }Как же верно реализовать?
Так происходит от непонимания принципа работы динамической индикации. А советы не помогают от того, что в коде каша.
#define DATA_PIN 4 #define LATCH_PIN 3 #define CLOCK_PIN 2 const byte digitPins[3] = {52,51,50}; byte disp[3]; void setup() { for(byte i = 0; i < 3; i++) pinMode(digitPins[i], OUTPUT); pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } void loop() { Steinhart(); Display(); } void Steinhart() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 500) return; pre_millis = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = (value/100)%10; //десятки disp[1] = (value/10)%10;//единицы disp[2] = value%10; //десятые } const byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; void Display() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 5) return; pre_millis = millis(); for(byte d = 0; d < 3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); byte out = 0; static byte digit = 0; if(digit == 1) out = ~(segments[disp[digit]] | B10000000); else out = ~segments[disp[digit]]; shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, out); digitalWrite(LATCH_PIN, HIGH); digitalWrite(digitPins[digit], HIGH); digit++; if(digit > 2) digit = 0; }Так же на анодах должны стоять PNP транзисторы, а не NPN.
Так происходит от непонимания принципа работы динамической индикации. А советы не помогают от того, что в коде каша.
#define DATA_PIN 4 #define LATCH_PIN 3 #define CLOCK_PIN 2 const byte digitPins[3] = {52,51,50}; byte disp[3]; void setup() { for(byte i = 0; i < 3; i++) pinMode(digitPins[i], OUTPUT); pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } void loop() { Steinhart(); Display(); } void Steinhart() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 500) return; pre_millis = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = (value/100)%10; //десятки disp[1] = (value/10)%10;//единицы disp[2] = value%10; //десятые } const byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; void Display() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 5) return; pre_millis = millis(); for(byte d = 0; d < 3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); byte out = 0; static byte digit = 0; if(digit == 1) out = ~(segments[disp[digit]] | B10000000); else out = ~segments[disp[digit]]; shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, out); digitalWrite(LATCH_PIN, HIGH); digitalWrite(digitPins[digit], HIGH); digit++; if(digit > 2) digit = 0; }Так же на анодах должны стоять PNP транзисторы, а не NPN.
Спасибо, сейчас проверю. Полнейшая каша:(
И если делаете готовое устройство, то лучше возьмите ATMEGA8 и избавьтесь от сдвигового регистра.
Так же запитайте все это дело не от 5 вольт, а от 3,0 - 3,3 вольта и тогда токоограничительные резисторы на катодах будут не нужны.
#include <math.h> // DS отвечает за поток битов(данные). На Схеме 595 пин 14 #define DATA_PIN 4 //STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12 #define LATCH_PIN 3 // SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11 #define CLOCK_PIN 2 const int digitPins[3] = {32,31,30}; //Массив пинов. Выбрал произвольные кониакты у меня Мега int8_t Disp[3]={0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало. int Value; int i = 0; int flag = 0;//0 - не нажата ни одна, 1 - нажата одна int regim ; //unsigned long previousMillis = 0;//отсечка //unsigned long time; int TimePush = 2000; #define ledPin1 22 #define ledPin2 23 byte Temp1 = 20; ////Температура Первого диапазона byte Temp2 = 28; //Температура Второго диапазона double TempRes; // Температура с терморезистора unsigned long previousMillis = 0; const long interval = 25000; unsigned long delta; byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; void setup() { // Serial.begin(115200); pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } void printInd() { for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, B11111111); digitalWrite(LATCH_PIN, HIGH); //delayMicroseconds(100); digitalWrite(digitPins[i], HIGH); digitalWrite(LATCH_PIN, LOW); if(i==1){ shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, ~(segments[Disp[i]] | B10000000));//print the decimal point on the 3rd digit } else shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, ~segments[Disp[i]]); digitalWrite(LATCH_PIN, HIGH); i++; if(i > 2) i=0; } double Steinhart (int value) { double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double B = 3988.0; // Параметр конкретного типа термистора (из datasheet) TempRes = (1.0 / (1.0 / (B)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; // 10KOm - R_25 Value=TempRes*10 ; //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //десятки Disp[1] = (Value/10)%10;//единицы Disp[2] = Value%10; //десятые unsigned long tt = millis(); while ( (millis() - tt) < 500 ) { printInd(); } return TempRes; } void click() { int VRes = analogRead(0); // значение с аналог пина if (flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 + { previousMillis = millis(); // когда нажата flag = 1; // состояние что нажата } if (flag == 1 && VRes<300 && VRes>0 && ((millis() - previousMillis) >= TimePush))flag = 2;// выполняем первый режим работы прибавление 5 ед. if (VRes > 1000 && flag > 0) { // отпустили кнопку смотрим сколько её держали switch (flag) { case 1: regim = 2; // короткое нажатие //прибавление единицы break; case 2: regim = 1; // длинное нажатие //прибавление 5 единиц break; } flag = 3; //кнопка отжата } //Два других режима по аналогии if (flag1 == 0 && VRes > 400 && VRes < 600) // нажата ли кнопка 2 - { previousMillis1 = millis(); // когда нажата flag1 = 1; // состояние что нажата } if (flag1 == 1 && VRes > 400 && VRes < 600 && ((millis() - previousMillis1) >= TimePush))flag1 = 2;// третий режим - отнимаем 5 ед. if (VRes > 1000 && flag1 > 0) { // отпустили кнопку смотрим сколько её держали switch (flag1) { case 1: regim = 4; // короткое нажатие //прибавление единицы break; case 2: regim = 3; // длинное нажатие //прибавление 5 единиц break; } flag1 = 3; //кнопка отжата } switch (regim) { case 1: Value += 5; regim = 0; flag = 0; break; case 2: Value++; regim = 0; flag = 0; break; case 3: Value -= 5; regim = 0; flag1 = 0; break; case 4: Value--; regim = 0; flag1 = 0; break; } if (flag1==3&&flag==0||flag1==0&&flag==3) //Защита при одновременном нажатии двух кнопок { flag1=0; flag=0; } } void releTime1(){ if((digitalRead(ledPin1)==HIGH&&digitalRead(ledPin2)==HIGH)||digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==LOW){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,LOW); previousMillis=millis(); delta = interval-millis()+previousMillis; } else if (digitalRead(ledPin1)==HIGH&&digitalRead(ledPin2)==LOW&&(previousMillis + delta)<= millis()){ digitalWrite(ledPin1,LOW); digitalWrite(ledPin2,HIGH); previousMillis = millis(); } else if (digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==HIGH&&(previousMillis + delta)<= millis()){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,LOW); previousMillis = millis(); } } void releTime2(){ if (digitalRead(ledPin1)==LOW||digitalRead(ledPin2)==LOW||digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==LOW){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,HIGH); } } void releTime3(){ if (digitalRead(ledPin1)==HIGH||digitalRead(ledPin2)==HIGH||digitalRead(ledPin1)==HIGH||digitalRead(ledPin2)==HIGH){ digitalWrite(ledPin1,LOW); digitalWrite(ledPin2,LOW); } } void loop() { click(); while (Temp1<Steinhart(analogRead(1)) && Temp2>Steinhart(analogRead(1)))releTime1(); while (Temp1<Steinhart(analogRead(1)) && Temp2<Steinhart(analogRead(1)))releTime2(); while (Temp1>Steinhart(analogRead(1)) && Temp2>Steinhart(analogRead(1)))releTime3(); }Вот так выглядит полный скетч
И если делаете готовое устройство, то лучше возьмите ATMEGA8 и избавьтесь от сдвигового регистра.
Так же запитайте все это дело не от 5 вольт, а от 3,0 - 3,3 вольта и тогда токоограничительные резисторы на катодах будут не нужны.
Как раз об этом думал от 3.3 запитать. Там входное на сегменты 2.5 и на цифры 5.0
Чуть завышенный ток при динамической индикации некритичен.
И если делаете готовое устройство, то лучше возьмите ATMEGA8 и избавьтесь от сдвигового регистра.
Attiny84 уже лежит:) Мне немножко раньше нужно было думать об этом - хотел малой кровью, а выходит проблемно.
Спасибо, ваш пример работает отлично, есть небольшое мирцание, но это некритично.
Уменьшите задержку засветки с 5, наример, до 2 в 57 строке.
if(millis()-pre_millis < 2) return;Уменьшите задержку засветки с 5, наример, до 2 в 57 строке.
if(millis()-pre_millis < 2) return;Так и сделал, до 3.
Теперь надо всё в солянку вставить))
Полный скетч
#include <Arduino.h> #include <math.h> // DS отвечает за поток битов(данные). На Схеме 595 пин 14 #define DATA_PIN 4 //STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12 #define LATCH_PIN 3 // SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11 #define CLOCK_PIN 2 const int digitPins[3] = {32,31,30}; //Массив пинов.На цифры сегмента 5в int8_t disp[3]={0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало. int Value; int i = 0; int flag = 0,flag1 = 0;//0 - не нажата ни одна, 1 - нажата одна int regim ; //unsigned long previousMillis = 0;//отсечка //unsigned long time; int TimePush = 2000; #define ledPin1 22 #define ledPin2 23 double TempRes; byte Temp1 = 20; ////Температура Первого диапазона byte Temp2 = 28; //Температура Второго диапазона unsigned long previousMillis = 0,previousMillis1 = 0; const long interval = 25000; unsigned long delta; const byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; double Steinhart() { static uint32_t pre_millis1 = 0; if(millis()-pre_millis1 < 400) return; pre_millis1 = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = (value/100)%10; //десятки disp[1] = (value/10)%10;//единицы disp[2] = value%10; //десятые Display(); return TemRes; } void Display() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 3) return; pre_millis = millis(); for(byte d = 0; d < 3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); byte out = 0; static byte digit = 0; if(digit == 1) out = ~(segments[disp[digit]] | B10000000); else out = ~segments[disp[digit]]; shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, out); digitalWrite(LATCH_PIN, HIGH); digitalWrite(digitPins[digit], HIGH); digit++; if(digit > 2) digit = 0; } void releTime1() { if((digitalRead(ledPin1)==HIGH&&digitalRead(ledPin2)==HIGH)||digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==LOW){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,LOW); previousMillis=millis(); delta = interval-millis()+previousMillis; } else if (digitalRead(ledPin1)==HIGH&&digitalRead(ledPin2)==LOW&&(previousMillis + delta)<= millis()){ digitalWrite(ledPin1,LOW); digitalWrite(ledPin2,HIGH); previousMillis = millis(); } else if (digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==HIGH&&(previousMillis + delta)<= millis()){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,LOW); previousMillis = millis(); } } void releTime2() { if (digitalRead(ledPin1)==LOW||digitalRead(ledPin2)==LOW||digitalRead(ledPin1)==LOW&&digitalRead(ledPin2)==LOW){ digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,HIGH); } } void releTime3() { if (digitalRead(ledPin1)==HIGH||digitalRead(ledPin2)==HIGH||digitalRead(ledPin1)==HIGH||digitalRead(ledPin2)==HIGH){ digitalWrite(ledPin1,LOW); digitalWrite(ledPin2,LOW); } } void click() { int VRes = analogRead(0); // значение с аналог пина if (flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 + { previousMillis = millis(); // когда нажата flag = 1; // состояние что нажата } if (flag == 1 && VRes<300 && VRes>0 && ((millis() - previousMillis) >= TimePush))flag = 2;// выполняем первый режим работы прибавление 5 ед. if (VRes > 1000 && flag > 0) { // отпустили кнопку смотрим сколько её держали switch (flag) { case 1: regim = 2; // короткое нажатие //прибавление единицы break; case 2: regim = 1; // длинное нажатие //прибавление 5 единиц break; } flag = 3; //кнопка отжата } //Два других режима по аналогии if (flag1 == 0 && VRes > 400 && VRes < 600) // нажата ли кнопка 2 - { previousMillis1 = millis(); // когда нажата flag1 = 1; // состояние что нажата } if (flag1 == 1 && VRes > 400 && VRes < 600 && ((millis() - previousMillis1) >= TimePush))flag1 = 2;// третий режим - отнимаем 5 ед. if (VRes > 1000 && flag1 > 0) { // отпустили кнопку смотрим сколько её держали switch (flag1) { case 1: regim = 4; // короткое нажатие //прибавление единицы break; case 2: regim = 3; // длинное нажатие //прибавление 5 единиц break; } flag1 = 3; //кнопка отжата } switch (regim) { case 1: Value += 5; regim = 0; flag = 0; break; case 2: Value++; regim = 0; flag = 0; break; case 3: Value -= 5; regim = 0; flag1 = 0; break; case 4: Value--; regim = 0; flag1 = 0; break; } if (flag1==3&&flag==0||flag1==0&&flag==3) //Защита при одновременном нажатии двух кнопок { flag1=0; flag=0; } } void setup() { pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } void loop() { click(); while (Temp1<Steinhart() && Temp2>Steinhart())releTime1(); while (Temp1<Steinhart() && Temp2<Steinhart())releTime2(); while (Temp1>Steinhart() && Temp2>Steinhart())releTime3(); }Как быть с этим, чтобы возвратить значение??
double Steinhart() { static uint32_t pre_millis1 = 0; if(millis()-pre_millis1 < 400) return; pre_millis1 = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = (value/100)%10; //десятки disp[1] = (value/10)%10;//единицы disp[2] = value%10; //десятые Display(); return TemRes; }Вы опять намешали все в кучу. Оставьте Display(); там где она была, не надо ее засовывать в другие функции, она там работать не будет. Переменную TempRes сделайте глобальной.
Вы опять намешали все в кучу. Оставьте Display(); там где она была, не надо ее засовывать в другие функции, она там работать не будет. Переменную TempRes сделайте глобальной.
double TempRes; void Steinhart() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 400) return; pre_millis = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = (value/100)%10; //десятки disp[1] = (value/10)%10;//единицы disp[2] = value%10; //десятые } void Display() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 3) return; pre_millis = millis(); for(byte d = 0; d < 3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); byte out = 0; static byte digit = 0; if(digit == 1) out = ~(segments[disp[digit]] | B10000000); else out = ~segments[disp[digit]]; shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, out); digitalWrite(LATCH_PIN, HIGH); digitalWrite(digitPins[digit], HIGH); digit++; if(digit > 2) digit = 0; } void loop() { click(); Steinhart(); Display(); if (Temp1<TempRes && Temp2>TempRes)releTime1(); if (Temp1<TempRes && Temp2<TempRes)releTime2(); if (Temp1>TempRes && Temp2>TempRes)releTime3(); }Правильно понимаю не while, a if надо?
Правильно. Только вот от циклов
while(...)надо избавляться, иначе как только дойдет до этой части программа зависнет.Правильно. Только вот от циклов
while(...)надо избавляться, иначе как только дойдет до этой части программа зависнет.не while, a if надо. До этого использовали потому что были кратковременны включения светодиодов.
Вот протестировал со льдом, всё, как нужно работает, буду теперь проверять. Спасибо Вам большое, что помогли. Еще паузу повысил до секунды в Steinhart(), иначе значение прыгает и выполняется условия реле(мигает)
Более оптимизировано:
const byte segments[10] = { B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111 //9 }; void Steinhart() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 500) return; pre_millis = millis(); int value = analogRead(1); double Vin = 5.0; // напряжение питания double voltage = value * Vin / 1023; double r1 = voltage * 9740.0 / (Vin - voltage); // 10 кОм - подтягивающий резистор double TempRes = (1.0 / (1.0 / (3988.0)*log(r1 / 10000.0) + 1.0 / (273.0 + 25.0))) - 273.0; value = TempRes * 10; disp[0] = ~segments[(value/100)%10]; //десятки disp[1] = ~(segments[(value/10)%10] | B10000000); //единицы disp[2] = ~segments[value%10]; //десятые } void Display() { static uint32_t pre_millis = 0; if(millis()-pre_millis < 5) return; pre_millis = millis(); for(byte d = 0; d < 3; d++) digitalWrite(digitPins[d], LOW); digitalWrite(LATCH_PIN, LOW); static byte digit = 0; shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, disp[digit]); digitalWrite(LATCH_PIN, HIGH); digitalWrite(digitPins[digit], HIGH); digit++; if(digit > 2) digit = 0; }