датчики стоят по разным помещениям. Индикаторы - на входе в каждое помещение. (Не дом) Перед дверью видишь индикатор с температурой внутри конкретного помещения. 3 двери = 3 индикатора. А отдельно, в кабинете (ну или дома лежа не диване) через комп видишь показания датчиков на мониторе. Processing - рулит. Прогу с датчиками своял (на комп показания идут) теперь задача - интегрировать туда индикацию с индикаторами.
Нашел интересный вариант отображения с использованием прерываний. С прерываниями я не знаком, пока еще.
Проект часов от Ghost_D - http://robocraft.ru/blog/3095.html
Из всего проекта выдернул только фрагмент для индикаторов. Правда Ghost_D использовал один регистр, но оченнь интересная реализация ShiftOut.
/*
Автор кода: Ghost_D
Проект: Wall-E Clock Shield. Своими руками.
Адрес исходный кода: http://robocraft.ru/blog/3095.html
*/
byte lckPin=9; //подключение 74HC595
byte clockPin=10; //подключение 74HC595
byte dataPin=8; //подключение 74HC595
//предустановка, времени нахождения в текущем режиме
#define timeReturnMode 5000
byte showDisp[4]; //это массив, который будет отображаться на индекаторах
byte segmNum[4]={6,4,5,3}; //массив пинов, к которым подключены катоды индикаторов, 1сегм. - pin 6, 2 сегм. - pin 4 и т.д.
// Это массив значений, которые нужно "загнать" в 74HC595, для отображения нужной цифры
// 0 1 2 3 4 5 6 7 8 9
byte Encode7seg[]={252,192, 181, 213, 201, 93, 125, 196, 253,221};
byte cur_digit=0;
void setup(){
pinMode(lckPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
for (byte z=0;z<4;z++)
{
pinMode(segmNum[z],OUTPUT);
}
//start ----------------- настраиваем прерывание по таймеру --------------
// для Atmega8 здесь нужно вносить изменения
// А тут на прерывания по таймеру будет вызываться процедура отображения сегментов
uint8_t prescaler = _BV(CS10); //ставим предделитель в 1
ICR1 = 28000; // задаем верхнее значение счетчика.
if (TCNT1 > 1024) TCNT1 = 28000; // Если значение счетчика больше, чем верхнее значение - корректируем.
TCCR1B = _BV(WGM13) | prescaler; // Ставим режим (PWM, phase and frequency corrected) и значение предделителя.
TCCR1A = _BV(COM1B0);
TIMSK1 |= _BV(OCIE1A); // Активируем прерывание.
//частота обновления одного сегмента ISR(TIMER1_COMPA_vect), будет 16000000/28000=571
//end ----------------- настраиваем прерывание по таймеру --------------
} //end setup
void loop(){
pushDataToDisp(10,30);
}
//-----------------------------------------------
// ОЧЕНЬ нужные процедуры и функции
//-----------------------------------------------
// Процедура отображения "содержимого" showDisp
ISR(TIMER1_COMPA_vect) {
/* Этот цикл - "кривой вариант обнуления" сегментов
if (cur_digit==0){
digitalWrite(segmNum[3],LOW);
}
else{
digitalWrite(segmNum[cur_digit-1],LOW);
}
*/
// а этот вариант обнуления сегментов гораздо красивее - 1 строчка
digitalWrite(segmNum[(cur_digit-1) & 3],LOW);
/*
Так как долго "висеть" на прерывании не рекомендуется, попробуем ускориться (переделаем ShiftOut)
В качестве аксиомы возьмем следующее: Как установить определенный пин в порту (не зацепив все остальные)?
PORTB |= _BV(PB5); - HIGH (установка Pin13 в HIGH)
PORTB &= ~_BV(PB5); -LOW (установка Pin13 в LOW)
--------------------------
Arduino Pin - Name
8 - PB0
9 - PB1
10 - PB2
11 - PB3
12 - PB4
13 - PB5
--------------------------
Но почему-то для Atmega328 нужно указывать не PB2, а PORTB2 ?!?!?! На куя????
Смотри ATMEGA8 and ATMEGA168 uses: /hardware/tools/avr/avr/include/avr/iomx8.h
ATMEGA328 uses: /hardware/tools/avr/avr/include/avr/iom328p.h
Итак, для нашего случая:
dataPin=8 - это PORTB0 (или PB0 для Atmega8/168)
clockPin=10 - это PORTB2 (или PB2 для Atmega8/168)
!!!! Естественно, предварительно эти порты должны быть настроены на OUTPUT!!!
----------------cut------------------
*/
digitalWrite(lckPin,LOW);
// shiftOut(dataPin,clockPin,MSBFIRST,showDisp[cur_digit]);
//стрелками выделен фрагмент "заменяющий" команду shiftOut
// ---> ниже фрагмент кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
for (int i=7; i>=0; i--) {
if(showDisp[cur_digit]&(1<<i)) PORTB |= _BV(PORTB0); //побитный сдвиг и запись 1- HIGH в соотв. пин
else PORTB &= ~_BV(PORTB0); //если 0, то пин ставим в LOW
//делаем тактовый "тик"
PORTB |= _BV(PORTB2);
PORTB &= ~_BV(PORTB2);
}//end for
// ---> конец фрагмента кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
digitalWrite(lckPin,HIGH);
digitalWrite(segmNum[cur_digit],HIGH);
cur_digit++;
if (cur_digit>3){
cur_digit=0;
}
}//end ISR
//---- процедура заполнения экранного буфера
void pushDataToDisp(byte firstInd, byte secondInd)
{
showDisp[0]=Encode7seg[(firstInd/10)];
showDisp[1]=Encode7seg[(firstInd%10)];
showDisp[2]=Encode7seg[(secondInd/10)];
showDisp[3]=Encode7seg[(secondInd%10)];
}//end pushDisp
Фрагмент полностью рабочий, но под мою идею (Вывод информации на 4 разрядный 7сегментный индикатор при помощи двух 74hc595) подходит не совсем. Тут я решил (что самый умный) и просто дважды вставил аналог ShiftOut, но реальность вновь расставила все точки над Ё :). Код рабочий, но не совсем - отображается только один разряд, первый указанный в массиве разрядов. Остальные в упор не хотят работать. Кто будет пробовать, не забудте поменять массивы значений для символов и разрядов на свои, т.к. тут вариант для моей самопальной платы.
/*
Автор кода: Ghost_D
Проект: Wall-E Clock Shield. Своими руками.
Адрес исходный кода: http://robocraft.ru/blog/3095.html
*/
byte lckPin=9; //подключение 74HC595
byte clockPin=10; //подключение 74HC595
byte dataPin=8; //подключение 74HC595
//предустановка, времени нахождения в текущем режиме
#define timeReturnMode 5000
byte SegDisplay; // переменная для вывода символов на индикаторе
byte RazrDisplay; // переменная для включения разрядов
// Это массив значений, которые нужно "загнать" в 74HC595, для отображения нужной цифры
byte g_digits[]={
B01000010, B11110110, // 0 1
B01101000, B01110000, // 2 3
B11010100, B01010001, // 4 5
B01000001, B11110010, // 6 7
B01000000, B01010000, // 8 9
B11111111, B11111101,}; // все сегменты выключены / -
// Это массив значений, которые нужно "загнать" в 74HC595, для отображения нужных разрядов индикатора
byte g_registerArray[]={
B00010000, B00001000, // +4 +3
B00000010, B00000001, // +2 +1
B00000100, }; // dp
void setup(){
pinMode(lckPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
//start ----------------- настраиваем прерывание по таймеру --------------
// для Atmega8 здесь нужно вносить изменения
// А тут на прерывания по таймеру будет вызываться процедура отображения сегментов
uint8_t prescaler = _BV(CS10); //ставим предделитель в 1
ICR1 = 28000; // задаем верхнее значение счетчика.
if (TCNT1 > 1024) TCNT1 = 28000; // Если значение счетчика больше, чем верхнее значение - корректируем.
TCCR1B = _BV(WGM13) | prescaler; // Ставим режим (PWM, phase and frequency corrected) и значение предделителя.
TCCR1A = _BV(COM1B0);
TIMSK1 |= _BV(OCIE1A); // Активируем прерывание.
//частота обновления одного сегмента ISR(TIMER1_COMPA_vect), будет 16000000/28000=571
//end ----------------- настраиваем прерывание по таймеру --------------
} //end setup
void loop(){
long disp = 7654; //создаем переменную для вывода на экран
// Разбиваем цифру по разрядам индикатора
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 10 );
disp /= 10;
}
}
//-----------------------------------------------
// ОЧЕНЬ нужные процедуры и функции
//-----------------------------------------------
// Процедура отображения "содержимого" showDisp
ISR(TIMER1_COMPA_vect) {
/*
Так как долго "висеть" на прерывании не рекомендуется, попробуем ускориться (переделаем ShiftOut)
В качестве аксиомы возьмем следующее: Как установить определенный пин в порту (не зацепив все остальные)?
PORTB |= _BV(PB5); - HIGH (установка Pin13 в HIGH)
PORTB &= ~_BV(PB5); -LOW (установка Pin13 в LOW)
--------------------------
Arduino Pin - Name
8 - PB0
9 - PB1
10 - PB2
11 - PB3
12 - PB4
13 - PB5
--------------------------
Но почему-то для Atmega328 нужно указывать не PB2, а PORTB2 ?!?!?! На куя????
Смотри ATMEGA8 and ATMEGA168 uses: /hardware/tools/avr/avr/include/avr/iomx8.h
ATMEGA328 uses: /hardware/tools/avr/avr/include/avr/iom328p.h
Итак, для нашего случая:
dataPin=8 - это PORTB0 (или PB0 для Atmega8/168)
clockPin=10 - это PORTB2 (или PB2 для Atmega8/168)
!!!! Естественно, предварительно эти порты должны быть настроены на OUTPUT!!!
----------------cut------------------
*/
digitalWrite(lckPin,LOW);
// shiftOut(dataPin,clockPin,MSBFIRST,showDisp[cur_digit]);
//стрелками выделен фрагмент "заменяющий" команду shiftOut
// ---> ниже фрагмент кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
for (int i=7; i>=0; i--) {
if(RazrDisplay&(1<<i)) PORTB |= _BV(PORTB0); //побитный сдвиг и запись 1- HIGH в соотв. пин
else PORTB &= ~_BV(PORTB0); //если 0, то пин ставим в LOW
//делаем тактовый "тик"
PORTB |= _BV(PORTB2);
PORTB &= ~_BV(PORTB2);
}//end for
// ---> конец фрагмента кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
// ---> ниже фрагмент кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
for (int i=7; i>=0; i--) {
if(SegDisplay&(1<<i)) PORTB |= _BV(PORTB0); //побитный сдвиг и запись 1- HIGH в соотв. пин
else PORTB &= ~_BV(PORTB0); //если 0, то пин ставим в LOW
//делаем тактовый "тик"
PORTB |= _BV(PORTB2);
PORTB &= ~_BV(PORTB2);
}//end for
// ---> конец фрагмента кода - "типа" САМОГО скоростного (ДЛЯ ARDUINO) ShiftOut
digitalWrite(lckPin,HIGH);
}
//---- процедура заполнения экранного буфера
void Indicate(int r,int x)
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
}
Может гуру подскажут в чем проблема моей реализации. Да и остальным, я думаю этот вариант будет интересен уже хотя бы тем что скорость мерцания настраивается и при данной настройке мерцания вообще не видно.
Моргают цифры и все, может структура неправильная для millis или не там скобочки ставлю. Помогите пожалуйста.
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(5);
DallasTemperature sensors(&oneWire);
float temp1=0;
DeviceAddress tempDeviceAddress;
long previousMillis1 = 0;
long interval1 = 1000; // интервал опроса датчиков температуры
int latchPin = 2; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 3; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 4; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay; // Переменная для вывода символов на индикаторе
byte RazrDisplay; // Переменная для включения разрядов
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B00111111, B00000110, B01011011, B01001111, B01100110, // 0 1 2 3 4
B01101101, B01111101, B00000111, B01111111, B01101111, // 5 6 7 8 9
B10111111, B10000110, B11011011, B11001111, B11100110, // 0. 1. 2. 3. 4.
B11101101, B11111101, B10000111, B11111111, B11101111, // 5. 6. 7. 8. 9.
B10000000, B01000000, B01100011, B00111001, // точка, прочерк, градус, цельсия
B00000000, }; // все сегменты выключены
byte g_registerArray[4]={~8,~4,~2,~1}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
sensors.begin();
sensors.getAddress(tempDeviceAddress, 0);
}
void loop()
{
//Модуль опроса датчиков и получения сведений о температуре
//Вызывается 1 раз в секунду
unsigned long currentMillis1 = millis();
if(currentMillis1 - previousMillis1 > interval1) {
previousMillis1 = currentMillis1;
//Запуск процедуры измерения температуры
sensors.requestTemperatures();
//Считывание значения температуры
sensors.getAddress(tempDeviceAddress, 0);
temp1=sensors.getTempC(tempDeviceAddress);
}
// Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temp1); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temp1 = (temp1 - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temp1)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
/* Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
*/
}
}
void Indicate(int r,int x)
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
Моргают цифры и все, может структура неправильная для millis или не там скобочки ставлю.
Я смотрю вы уже датчик прикрутили. Я пока не делал. Буду на выходных кумекать. Про проблему мерцания слышал. Это и есть призрачность простоты Arduino. Надо работать с 1-wire в прерываниях чтоб не останавливать динамику индикации.
На соседнем форуме человек писал по этой проблеме:
"если пользовать стандартную функцию то так и будет.
время измерения 0,5 сек примерно, на эти 0,5 сек все останавливается.
Если работать напрямую с датчиком, можно подать команду на имерение температуры и пока идет измерение продолжить вывод индикации". Там же человек предлагает свое решение проблемы. Нужно вникнуть.
По DS18B20, подали команду на конвертацию, ушли, через 750мС вернулись и считали температуру - это чисто по 1-Wire. По DHT - надо библиотеку править, так просто не выходит.
По DS18B20, подали команду на конвертацию, ушли, через 750мС вернулись и считали температуру - это чисто по 1-Wire. По DHT - надо библиотеку править, так просто не выходит.
Может есть пример кода, где можно посмотреть как реализовано.
что то вроде этого должно быть. но это для 1 термодатчика. для нескольких надо поправить
#include <OneWire.h>
OneWire ds (A5);
byte data[12];
float celsius;
int raw;
unsigned long time=0;
boolean flag=1;
void setup() {
}
void loop(){
if(flag) {
DS_start();
time=millis();
flag=0;
}
if((millis()-time)>750 && !flag){
DS_read();
flag=1;
}
//а здесь постоянно выводим. температуру брать из celsius
}
void DS_start(){
ds.reset();
ds.write(0xCC);
ds.write(0x44); // start conversion, with parasite power on at the end
}
void DS_read(){
ds.reset();
ds.write(0xCC);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read ();
}
raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру
celsius = (float)raw / 16.0;
}
Спасибо! Но не получается, у меня вывод Indicate как функция, внутрь loop не вставляется. Вобщем не понимаю в чем проблем. Теперь значение меняются 0 потом моргнет температурой снова 0.
#include <OneWire.h>
OneWire ds (5);
byte data[12];
float temperature;
int raw;
unsigned long time=0;
boolean flag=1;
int latchPin = 2; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 3; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 4; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay; // Переменная для вывода символов на индикаторе
byte RazrDisplay; // Переменная для включения разрядов
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B00111111, B00000110, B01011011, B01001111, B01100110, // 0 1 2 3 4
B01101101, B01111101, B00000111, B01111111, B01101111, // 5 6 7 8 9
B10111111, B10000110, B11011011, B11001111, B11100110, // 0. 1. 2. 3. 4.
B11101101, B11111101, B10000111, B11111111, B11101111, // 5. 6. 7. 8. 9.
B10000000, B01000000, B01100011, B00111001, // точка, прочерк, градус, цельсия
B00000000, }; // все сегменты выключены
byte g_registerArray[4]={~8,~4,~2,~1}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop(){
if(flag) {
DS_start();
time=millis();
flag=0;
}
if((millis()-time)>750 && !flag){
DS_read();
flag=1;
}
// Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temperature); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temperature = (temperature - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temperature)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
}
void Indicate(int r,int x)
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
void DS_start(){
ds.reset();
ds.write(0xCC);
ds.write(0x44); // start conversion, with parasite power on at the end
}
void DS_read(){
ds.reset();
ds.write(0xCC);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read ();
}
raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру
temperature = (float)raw / 16.0;
}
например десятые. это проще понять если отправить измеренную температуру в uart
насколько помню там один или два знака после запятой (смотреть в терминале). и значит просто домножать на 10 или 100. и не нужно доп. переменных что до запятой, что после
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
когда выводишь цифру с точкой просто к коду который передается просто цифры , например 3 B01001111. первый ноль управляет точкой
значит когда передаешь для 2 разряда (например у тебя 2 разряд с точкой, всегда в одном месте!!!) нужно передать еще точку B01001111|B10000000. и все)
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
Не согласен. У меня в коде точка ни на одом месте. Плавает да еще как! Да если и в одном поставить, то получится что плюсовая температура максимум будет 99,99 и минусовая -9,99
Я у себя могу видеть плюслвую 999,9 и 99,99 а минусовую -99,9 и -9,99 т.е. значительно расширяется диапазон измеряемых температур, а ноль (если чистый ноль без десятых и сотых) - вообще выводится как 0 градусов (значек) С. Спросите для чего? Проекты могут быть разные: для погоды - одно (можно и без сотых обойтись); для инкубатора - другое (там и сотые играют роль) в коптильне или автоклаве - третье (там температуры зачастую превышают 100 градусов... и т.д.
например десятые. это проще понять если отправить измеренную температуру в uart
насколько помню там один или два знака после запятой (смотреть в терминале). и значит просто домножать на 10 или 100. и не нужно доп. переменных
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
когда выводишь цифру с точкой просто к коду который передается просто цифры , например 3 B01001111. первый ноль управляет точкой
значит когда передаешь для 2 разряда (например у тебя 2 разряд с точкой, всегда в одном месте!!!) нужно передать еще точку B01001111|B10000000. и все)
Точка будет плавать, это заготовка для Борт комп авто (будут и другие переменные кроме темп). Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий. Я особо в коде не разбираюсь, код писали CheBuraw и Nemo.
Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий.
А вот тут я согласен полностью. У меня в проекте тоже предусмотрены и другие переменные, и другие индикаторы. Обещаю подумать, но только на выходных. Ща, цука, некогда. Работа мешает. Но решение где то рядом. Стулом чую.
Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий.
А вот тут я согласен полностью. У меня в проекте тоже предусмотрены и другие переменные, и другие индикаторы. Обещаю подумать, но только на выходных. Ща, цука, некогда. Работа мешает. Но решение где то рядом. Стулом чую.
А я с работы захожу к себе на рабочий стол через TeamViewer там меняю код и смотрю что получится на индикаторе через ваб камеру ))
Плюс не выводится. Если без знака, то априори - положительное значение. Выводится будет 18,75 и -18,7
Считаю это оптимальным, так как при положительных температурах гораздоо чаще сотые играют роль чем при отрицательных. ИХМО. На вскидку - не придумал проекта где сотые в отрицательных значениях играют роль. При положительных - тот же инкубатор.
Плюс не выводится. Если без знака, то априори - положительное значение. Выводится будет 18,75 и -18,7
Считаю это оптимальным, так как при положительных температурах гораздоо чаще сотые играют роль чем при отрицательных. ИХМО. На вскидку - не придумал проекта где сотые в отрицательных значениях играют роль. При положительных - тот же инкубатор.
Неа, как птицевод говорю, не родилась еще та курица, которая свой терморежим с сотыми поддерживает. Десятые и те плюс минус.
Код из поста №47 при компиляции в памяти занимает:
Sketch uses 1 378 bytes (4%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
А перенеся основной код в функцию (добавив буквально пару строк) и оставив в основном цыкле 1 строку - вызов функции, при компиляции получаем уже:
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
т.е. в 2 раза больше от первоначального варианта. Получается - чем больше мы чистим код и переносим действий в функции (сокращая тем самым основное тело программы), тем больше места мы занимаем в памяти Дуни?
А что же будет, если функции перенести в библиотеки? Еще больше?
хотя может разница в том что ты используешь наверно версию 1.6.0, а я 1.0.6
поставь 1.0.6 и меньше проблемм у тебя будет
Наверное. У меня стоит 1.5.8
Проверил на версии 1.0.6
Размер скетча в двоичном коде: 2 782 байт (из 32 256 байт максимум)
В версии 1.6.0
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
jeka_tm, какая у Вас интересная модификация Arduino IDE. Подскажите, пожалуйста как себе сделать такую же? Где и какие плагины скачать или это как-то подругому делается?
jeka_tm, какая у Вас интересная модификация Arduino IDE. Подскажите, пожалуйста как себе сделать такую же? Где и какие плагины скачать или это как-то подругому делается?
Nemo вот один и второй код. проверь еще раз. хз что ты тестируешь
int latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay; // Переменная для вывода символов на индикаторе
byte RazrDisplay; // Переменная для включения разрядов
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
float temperature = 1.23; // Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temperature); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temperature = (temperature - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temperature)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
/* Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
*/
}
}
void Indicate(int r,int x) // Функция собственно, отображения цыфр на индикаторе.
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
int latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay; // Переменная для вывода символов на индикаторе
byte RazrDisplay; // Переменная для включения разрядов
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
temper();
}
void temper(){
float temperature = 1.23; // Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temperature); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temperature = (temperature - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temperature)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
/* Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
*/
}
}
void Indicate(int r,int x) // Функция собственно, отображения цыфр на индикаторе.
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
jeka_tm Да тот же код и тестирую. Вот что в версии 1.6.1 :
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
Вот код:
int latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
ledDigitDisplay(17.25); // Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
}
void ledDigitDisplay(float temperature)
{ // функция работы с числом: определение целой и дробной частей, положительного или отрицательного значения
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temperature); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temperature = (temperature - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temperature)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
/* Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
*/
}
}
void Indicate(byte r, byte x) // Функция собственно, отображения цыфр на индикаторе.
{
byte TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
byte RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
разговор шел просто перенести в функцию. про передачу значений разговора не было
2886 получается
а если передавать не float а int число и byte число знаков после запятой то остается как есть))
int latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5; // Время для разогрева сегментов
byte SegDisplay; // Переменная для вывода символов на индикаторе
byte RazrDisplay; // Переменная для включения разрядов
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
temper(123, 2);
}
void temper(int temperature, byte razryad){
int disp; // Переменная для целых чисел температуры
int disp_sot; // Переменная для дробной части числа
disp = int (temperature); // Избавляемся от десятых и сотых (оставляем челую часть числа)
temperature = (temperature - disp) * 100; // Переводим десятые и сотые в целую часть числа
disp_sot = int (abs(temperature)); // Обрубаем значения после запятой (оставляем целую часть числа) модуль - для избавления от минуса
// Разбиваем цифру по разрядам индикатора
if (disp < 0) // Если значение минусовое, то выполняется следующее условие
{
disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
/* Допустим наша цифра 25.
Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
В нашем случае это и есть та самая 5.
Аналогичным образом разбивается наша цифра и далее.
*/
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд десятую долю цифры
Indicate(2, disp + 10); // пишем в третий разряд нашу цифру с точкой
Indicate(3, 21); // пишем в четвертый разряд минус
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(2, disp / 10); // пишем в третий разряд - цифру делёную на 10
Indicate(3, 21); // пишем в четвертый разряд минус
}
else
{
Indicate(0, 21); // Думаю что температура ниже 99 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
}
else if (disp == 0) // Значение температуры ровно 0 градусов
{
Indicate(0, 23); // пишем в первый разряд - символ цельсия "С"
Indicate(1, 22); // пишем во второй разряд - символ градуса
Indicate(2, disp); // пишем в третий разряд - цифру ноль
Indicate(3, 24); // пишем в четвертый разряд пусто
}
else // Если значение положительное, то выполняется следующий цикл
{
if (disp < 10) // если наша цифра меньше 10, то
{
Indicate(0, 22); // пишем в первый разряд символ градуса
Indicate(1, disp_sot % 10); // пишем во второй разряд сотую долю цифры
Indicate(2, disp_sot / 10); // пишем в третий разряд десятую долю цифры
Indicate(3, disp + 10); // пишем в четвертый разряд нашу цифру с точкой
}
else if (disp < 100) // если наша цифра меньше 100, то
{
Indicate(0, disp_sot % 10); // пишем в первый разряд - сотую долю цифры
Indicate(1, disp_sot / 10); // пишем во второй разряд - десятую долю цифры
Indicate(2, (disp % 10) + 10); // пишем в третий разряд - цифру оставшуюся от деления на 10 с точкой
Indicate(3, disp / 10); // пишем в четвертый разряд - цифру делёную на 10
}
else if (disp < 1000) // если наша цифра меньше 1000, то
{
Indicate(0, disp_sot / 10); // пишем в первый разряд - десятую долю цифры
Indicate(1, (disp % 10) + 10); // пишем во второй разряд - последнюю целую цифру с точкой
Indicate(2, (disp % 100) / 10); // пишем в третий разряд - цифру оставшуюся от деления на 100
Indicate(3, (disp / 100)); // пишем в четвертый разряд - цифру делёную на 100
}
else // перестраховаться, на случай если вы засунете свой термометр в доменную печь
{
Indicate(0, 21); // Думаю что температура выше 999 градусов
Indicate(1, 21); // вряд ли возможна, поэтому
Indicate(2, 21); // выводим прочерки во всех регистрах
Indicate(3, 21);
}
/* Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
for( int i = 0; i < 4; i++ )
{
if( i == 0 || disp != 0 )
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
*/
}
}
void Indicate(int r,int x) // Функция собственно, отображения цыфр на индикаторе.
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
разговор шел просто перенести в функцию. про передачу значений разговора не было
2886 получается
а если передавать не float а int число и byte число знаков после запятой то остается как есть))
Ясно. Значит всё из за float...
Двумя переменным не хочу передавать, я ж с плавающей точкой все мучу. Поэтому передавать четко 2 знака после запятой не хотел. Передаю только 1 параметр, а внутри уже определяюсь с разрядами, минусами и т.д.
так можно тремя переменными. первая знак, вторая до запятой, треться после запятой
Да. Но для этого нужно значение разкладывать на три переменные до вызова функции. А у меня получается вся работы выполняется уже внутри функции. А передаем только конкретное значение температуры. И в основном цыкле программы фигурирует только одна строка:
void loop()
{
ledDigitDisplay(17.25); // Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
}
Я это делал для того делал, чтобы следующим шагом запихнуть две функции void ledDigitDisplay() и void Indicate() в библиотеку, тем самым минимизировать до самого небалуйся код основной программы.
так можно тремя переменными. первая знак, вторая до запятой, треться после запятой
Да. Но для этого нужно значение разкладывать на три переменные до вызова функции. А у меня получается вся работы выполняется уже внутри функции. А передаем только конкретное значение температуры. И в основном цыкле программы фигурирует только одна строка:
void loop()
{
ledDigitDisplay(17.25); // Можете подставить любые значения. Следите чтобы стояла именно . (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
}
Я это делал для того делал, чтобы следующим шагом запихнуть две функции void ledDigitDisplay() и void Indicate() в библиотеку, тем самым минимизировать до самого небалуйся код основной программы.
Переделал код. В старом около-нулевые значения не корректно обрабатывались.
Да и код получился покороче. Хотя и по замороченей. По строкам - особо много не выиграл, но по размеру занимаемой памяти улучшения налицо. Гляньте, а лучше потестите, кто заинтересован. Возможно еще что-то упустил.
// Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
int latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
ledDigitDisplay(12.34); // Можете подставить любые значения.
// Следите чтобы стояла именно "." (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
// Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
// max - потому что int-диапазон только до 32767
// min - потому что в не думаю что где то меньше значение потребуется
}
void ledDigitDisplay(float temperature)
{
int disp; // Переменная для целых чисел температуры
int floatingPoint = 0; // Переменная "плавающая точка" для хранения номера регистра в котором стоит "."
int index;
disp = temperature * 100; // Избавляемся от десятых и сотых (оставляем челую часть числа)
if (disp < 0) disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
if (disp > 9999) disp = int (disp / 10); // сдвиг до отображения только десятых в положительном диапазоне > 99.99
if (temperature <= -10) disp = int (disp / 10); // сдвиг до отображения только десятых в отрицательных диапазонах < -10
// Определяемся в каком именно разряде ставить точку
if ((temperature <= -10 && temperature > -100) || (temperature > 100 && temperature < 1000))
floatingPoint = 1;
else
if ((temperature < 0 && temperature > -10) || (temperature > 0 && temperature < 100))
floatingPoint = 2;
else floatingPoint = 4;
if (temperature < -99.99 || temperature > 327.67)
{
// Обработаем выход за пределы min и max температур
for (int i = 0; i < 4; i++)
Indicate( i, 21 ); // Ставим во всех разрядах прочерки
}
else
{
if(temperature < 0) Indicate( 3, 21 ); // если значение минусовое то ставим минус в первом индикаторе
if((disp / 100) < 1) Indicate( 2, 10 );
if((disp / 10) < 1) Indicate( 1, 0 );
if(temperature >= 0) index = 4;
else index = 3;
// Собственно, основной цыкл. Тут все и происходит
for (int i = 0; i < index; i++)
{
if (i == 0 || disp != 0)
if (i == 1 && floatingPoint == 1 || i == 2 && floatingPoint == 2)
Indicate( i, (disp % 10) + 10 );
else
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
}
}
void Indicate(byte r, byte x) // Функция собственно, отображения цыфр на индикаторе.
{
byte TimeLight = 1; // Время для разогрева сегментов - не более 2, иначе будет мерцание около-нулевых значений
byte SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
byte RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
Sketch uses 1 536 bytes (4%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
Из минусов - перестал отображаться 0 в формате "0 градусов цельсия" как было в старой версии кода. Но подумав, не стал дописывать, так как все равно все остальные значения отображаются без знака градуса.
Правда там код длинный. Придется разбираться долго. Чужие коды мне сложно для чтения даются. Не программист я по жизни. Так. Любитель.
Да. Код забыл:
#include <OneWire.h>
// Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
byte latchPin = 8; // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
byte clockPin = 12; // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
byte dataPin = 11; // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
B11000000, B11111001, B10100100, B10110000, B10011001, // 0 1 2 3 4
B10010010, B10000010, B11111000, B10000000, B10010000, // 5 6 7 8 9
B01000000, B01111001, B00100100, B00110000, B00011001, // 0. 1. 2. 3. 4.
B00010010, B00000010, B01111000, B00000000, B00010000, // 5. 6. 7. 8. 9.
B01111111, B10111111, B10011100, B11000110, // точка, прочерк, градус, цельсия
B11111111, }; // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды
OneWire ds (10); // Пин где подвешен ds18b20
byte data[12];
float celsius; // Переменная для хранения измеренной температуры
int raw;
unsigned long time=0;
boolean flag=1;
void setup()
{ // обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
if(flag)
{
DS_start();
time=millis();
flag=0;
}
if((millis()-time) > 750 && !flag)
{
DS_read();
flag=1;
}
//а здесь постоянно выводим. температуру брать из celsius
ledDigitDisplay(celsius); // Можете подставить любые значения.
// Следите чтобы стояла именно "." (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
// Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
// max - потому что int-диапазон только до 32767
// min - потому что в не думаю что где то меньше значение потребуется
}
void DS_start()
{
ds.reset();
ds.write(0xCC);
ds.write(0x44); // начать преобразования, с паразитным питанием на в конце
}
void DS_read()
{
ds.reset();
ds.write(0xCC);
ds.write(0xBE); // Чтение Scratchpad
for (byte i = 0; i < 9; i++)
{ // нам нужно 9 байт (с сотыми после запятой)
data[i] = ds.read ();
}
raw = (data[1] << 8) | data[0]; // Пересчитываем в температуру
celsius = (float)raw / 16.0;
}
void ledDigitDisplay(float temperature)
{
int disp; // Переменная для целых чисел температуры
int floatingPoint = 0; // Переменная "плавающая точка" для хранения номера регистра в котором стоит "."
int index;
disp = temperature * 100; // Избавляемся от десятых и сотых (оставляем челую часть числа)
if (disp < 0) disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
if (disp > 9999) disp = int (disp / 10); // сдвиг до отображения только десятых в положительном диапазоне > 99.99
if (temperature <= -10) disp = int (disp / 10); // сдвиг до отображения только десятых в отрицательных диапазонах < -10
// Определяемся в каком именно разряде ставить точку
if ((temperature <= -10 && temperature > -100) || (temperature > 100 && temperature < 1000))
floatingPoint = 1;
else
if ((temperature < 0 && temperature > -10) || (temperature > 0 && temperature < 100))
floatingPoint = 2;
else floatingPoint = 4;
if (temperature < -99.99 || temperature > 327.67)
{
// Обработаем выход за пределы min и max температур
for (int i = 0; i < 4; i++)
Indicate( i, 21 ); // Ставим во всех разрядах прочерки
}
else
{
if(temperature < 0) Indicate( 3, 21 ); // если значение минусовое то ставим минус в первом индикаторе
if((disp / 100) < 1) Indicate( 2, 10 );
if((disp / 10) < 1) Indicate( 1, 0 );
if(temperature >= 0) index = 4;
else index = 3;
// Собственно, основной цыкл. Тут все и происходит
for (int i = 0; i < index; i++)
{
if (i == 0 || disp != 0)
if (i == floatingPoint)
Indicate( i, (disp % 10) + 10 );
else
Indicate( i, disp % 10 );
else
Indicate( i, 24 );
disp /= 10;
}
}
}
void Indicate(byte r, byte x) // Функция собственно, отображения цыфр на индикаторе.
{
byte TimeLight = 1; // Время для разогрева сегментов - не более 2, иначе будет мерцание около-нулевых значений
byte SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
byte RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа)
shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
1. Писать неблокирующий 1-Wire.
2. Вывод индикации делать в прерывании по таймеру, а в библиотеке OneWire убрать запрет прерываний.
А можно подробнее? Просто край как необходимо разобраться. Все мои проекты с дуней связаны с датчиком ds18b20. Как это - неблокирующий 1-Wire? Читал что можно отправить запрос на измерение, потом продолжить индикацию, а после ответа от датчика уже обработать результат. Но как это реализовать - непонятно. Ткните носом пожалуйста куда посмотреть?
bwn пишет:
Через millis().
если в теории, мне нужно накопить минуту в переменной после запуска программы, затем измерить температуру, затем снова вернуться к накоплению минуты? А как быть с обнулением через 50 суток? И можно ли производить другие действия пока millis() будет минуту накапливать?
Читал что проблему мерцания через millis() решить можно. Только чет не пойму я этот оператор. Без параметров. Возвращает кол-во милисекунд с моментв выполнения текущей программы: т.е. с момента загрузки скетча в дуню или с момента включения уже загруженной дуни в сеть питания? А если она не выключалась? Работает круглосуточно? Сплошная каша.
Я тут подумал, если это возможно, выводимую переменную сделать как типа long которая запоминает последнее значение и ее обновлять уже датчиком, тоесть если не будет цифры с датчика то она покажет предыдущее значение, прокатит? )
Я тут подумал, если это возможно, выводимую переменную сделать как типа long которая запоминает последнее значение и ее обновлять уже датчиком, тоесть если не будет цифры с датчика то она покажет предыдущее значение, прокатит? )
Если я правильно понимаю, наша проблема с мерцанием именно в измерении датчика. Он меряет примерно 0,5 сек. на это время и происходит мигание. Т.е. если делать как вы предлагаете, то от измерения мы никуда не уходим. И сохранять его хоть в переменную, хоть сразу на вывод пускать, все равно теряем 0,5 сек. Да? Или я туплю?
Но для вашей задачи думаю есть еще и третий вариант - более равномерно пользоваться методами библиотеки OneWire при помощи конечного автомата. И да измерять раз в секунду температуру безссмысленно, более чем достаточно раз в 30 секунд.
Nemo, Sirox, для начала прочтите это . Код который вам дал jeka_tm, уже убрал задержку на конвертацию и осталось только считывание данных. Разница между началом конвертации и считыванием, сделано с помощью millis(). Обнуление через 50 суток, приведет к одному пропуску считывания, дальше все пойдет по кругу.
Т.к. у maksim опыта намного больше моего, он вам предлагает более изящные, но и более сложные варианты. Чем воспользоватся в данном случае, решать вам. Мое предложение не убирает мерцание, а делает его более редким.
Попробовал оба кода. Оба работают без мерцания! Супер!
Не знаю, какой из них подойдет для моей затеи с несколькими датчиками, но для проекта с 1 датчиком и 1 индикатором - уже можно брать и работать. Готовый, рабочий код. (проверял правда пока только в положительном диапазоне температур).
А несколько датчиков - пока не смогу попробовать, так как даттчики есть, а шилд-индикатор только один. Нужно решить, то ли заказать еще (маловат сам индикатор в размерах), то ли докупить микросхем 74hс595 и напаять своих (индикаторы есть побольше в размере, правда с общим анодом). Подумаю, просчитаю что выгоднее по деньгам, тогда решу... Ну это позже.
Остальсь только разобраться в самом коде. А это посложнее будет... Можно я буду вопросы по коду задавать где непонятно?
Например:
1 ) - я правильно понял что размер задержки в первом коде (10 секунд) вы задаете единожды в строке номер 30, а во вторм коде - тоже единожды но уже 30 сек. в строке номер 75 ?
2) - я правильно понял что как сказал выше bwn в обоих случаях мы не убираем мерцание, а делаем его более редким (раз в 10 и 30 секунд соответственно)?
bwn - спасибо за ссылку и совет. Обязательно вникну. Давно хотел разобраться с этой millis()
p/s/ Для кого критично: по ресурсоемкости первый код чуть более легче чем второй. Не на много.
Sketch uses 3 030 bytes (9%) of program storage space. Maximum is 32 256 bytes.
Global variables use 50 bytes (2%) of dynamic memory, leaving 1 998 bytes for local variables. Maximum is 2 048 bytes.
Против
Sketch uses 3 092 bytes (9%) of program storage space. Maximum is 32 256 bytes.
Global variables use 65 bytes (3%) of dynamic memory, leaving 1 983 bytes for local variables. Maximum is 2 048 bytes.
Судя по тому, что у вас мерцание исчезло вовсе, дело было не в задержке от считывания с датчика, а в перерисовке дисплея. Соответственно код Жеки тоже рабочий, только надо было добавить интервал между измерениями. Во втором коде maksim-а вы упустили 48 строку, а она важная.
Погонять несколько датчиков можете и сейчас для тренировки - пожертвуйте знаком минус и выводите в этот разряд номер отображаемого датчика.
Также попробуйте понять, где грабли в первом коде maksim-а.
Задача несколько другая.
датчики стоят по разным помещениям. Индикаторы - на входе в каждое помещение. (Не дом) Перед дверью видишь индикатор с температурой внутри конкретного помещения. 3 двери = 3 индикатора. А отдельно, в кабинете (ну или дома лежа не диване) через комп видишь показания датчиков на мониторе. Processing - рулит. Прогу с датчиками своял (на комп показания идут) теперь задача - интегрировать туда индикацию с индикаторами.
p/s/ а как код свернуть, чтобы страницу не раздувать?
Сам недавно этот вопрос задавал :)
Нашел интересный вариант отображения с использованием прерываний. С прерываниями я не знаком, пока еще.
Проект часов от Ghost_D - http://robocraft.ru/blog/3095.html
Из всего проекта выдернул только фрагмент для индикаторов. Правда Ghost_D использовал один регистр, но оченнь интересная реализация ShiftOut.
Фрагмент полностью рабочий, но под мою идею (Вывод информации на 4 разрядный 7сегментный индикатор при помощи двух 74hc595) подходит не совсем. Тут я решил (что самый умный) и просто дважды вставил аналог ShiftOut, но реальность вновь расставила все точки над Ё :). Код рабочий, но не совсем - отображается только один разряд, первый указанный в массиве разрядов. Остальные в упор не хотят работать.
Кто будет пробовать, не забудте поменять массивы значений для символов и разрядов на свои, т.к. тут вариант для моей самопальной платы.
Может гуру подскажут в чем проблема моей реализации. Да и остальным, я думаю этот вариант будет интересен уже хотя бы тем что скорость мерцания настраивается и при данной настройке мерцания вообще не видно.
Моргают цифры и все, может структура неправильная для millis или не там скобочки ставлю. Помогите пожалуйста.
Моргают цифры и все, может структура неправильная для millis или не там скобочки ставлю.
Я смотрю вы уже датчик прикрутили. Я пока не делал. Буду на выходных кумекать. Про проблему мерцания слышал. Это и есть призрачность простоты Arduino. Надо работать с 1-wire в прерываниях чтоб не останавливать динамику индикации.
время измерения 0,5 сек примерно, на эти 0,5 сек все останавливается.
Если работать напрямую с датчиком, можно подать команду на имерение температуры и пока идет измерение продолжить вывод индикации". Там же человек предлагает свое решение проблемы. Нужно вникнуть.
Сам пока не дошел. Если кто в курсе - подскажите.
Как реализовать короткий цыкл с плавающей точкой с десятыми и сотыми, пока не придумал
Тут вроде компактно высчитывается с точкой и минусами, может что пригодится.
По поводу избавления мерцания нашол щас темку, может тоже поможет http://arduino.ru/forum/programmirovanie/otkaz-ot-delay. В коде у меня знаний не хватает, не програмист я ни разу.
По DS18B20, подали команду на конвертацию, ушли, через 750мС вернулись и считали температуру - это чисто по 1-Wire. По DHT - надо библиотеку править, так просто не выходит.
По DS18B20, подали команду на конвертацию, ушли, через 750мС вернулись и считали температуру - это чисто по 1-Wire. По DHT - надо библиотеку править, так просто не выходит.
Может есть пример кода, где можно посмотреть как реализовано.
Вот в этом коде так сделано.
Чет с него улетает - 270 пост.
что то вроде этого должно быть. но это для 1 термодатчика. для нескольких надо поправить
что то вроде этого должно быть. но это для 1 термодатчика. для нескольких надо поправить
Спасибо! Но не получается, у меня вывод Indicate как функция, внутрь loop не вставляется. Вобщем не понимаю в чем проблем. Теперь значение меняются 0 потом моргнет температурой снова 0.
как то замороченно сделано по моему
например десятые. это проще понять если отправить измеренную температуру в uart
насколько помню там один или два знака после запятой (смотреть в терминале). и значит просто домножать на 10 или 100. и не нужно доп. переменных что до запятой, что после
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
когда выводишь цифру с точкой просто к коду который передается просто цифры , например 3 B01001111. первый ноль управляет точкой
значит когда передаешь для 2 разряда (например у тебя 2 разряд с точкой, всегда в одном месте!!!) нужно передать еще точку B01001111|B10000000. и все)
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
Не согласен. У меня в коде точка ни на одом месте. Плавает да еще как! Да если и в одном поставить, то получится что плюсовая температура максимум будет 99,99 и минусовая -9,99
Я у себя могу видеть плюслвую 999,9 и 99,99 а минусовую -99,9 и -9,99 т.е. значительно расширяется диапазон измеряемых температур, а ноль (если чистый ноль без десятых и сотых) - вообще выводится как 0 градусов (значек) С. Спросите для чего? Проекты могут быть разные: для погоды - одно (можно и без сотых обойтись); для инкубатора - другое (там и сотые играют роль) в коптильне или автоклаве - третье (там температуры зачастую превышают 100 градусов... и т.д.
Терятеся универсальность.
как то замороченно сделано по моему
например десятые. это проще понять если отправить измеренную температуру в uart
насколько помню там один или два знака после запятой (смотреть в терминале). и значит просто домножать на 10 или 100. и не нужно доп. переменных
и еще массив символов цифры и цифры с точкой. зачем? точка вроде не плавает у тебя по дисплею а всегда в одном месте. количество знаков после запятой всегда одно и тоже. используй это
когда выводишь цифру с точкой просто к коду который передается просто цифры , например 3 B01001111. первый ноль управляет точкой
значит когда передаешь для 2 разряда (например у тебя 2 разряд с точкой, всегда в одном месте!!!) нужно передать еще точку B01001111|B10000000. и все)
Точка будет плавать, это заготовка для Борт комп авто (будут и другие переменные кроме темп). Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий. Я особо в коде не разбираюсь, код писали CheBuraw и Nemo.
Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий.
А вот тут я согласен полностью. У меня в проекте тоже предусмотрены и другие переменные, и другие индикаторы. Обещаю подумать, но только на выходных. Ща, цука, некогда. Работа мешает. Но решение где то рядом. Стулом чую.
Это ничего страшного, просто нужно как то организовать структуру подругому чтобы было удобно выводить разные переменные и не было морганий.
А вот тут я согласен полностью. У меня в проекте тоже предусмотрены и другие переменные, и другие индикаторы. Обещаю подумать, но только на выходных. Ща, цука, некогда. Работа мешает. Но решение где то рядом. Стулом чую.
А я с работы захожу к себе на рабочий стол через TeamViewer там меняю код и смотрю что получится на индикаторе через ваб камеру ))
так вот оно что. делаете универсальный код значит
тогда вопрос. допустим температура 18,75 и -18,75. как каждая будет выглядеть?
так? 18,75 и -18,7
или так? 18,7 и -18,7
то есть минус съедает разряд или для него всегда пустое место? и вместо него например + выводится
Плюс не выводится. Если без знака, то априори - положительное значение. Выводится будет 18,75 и -18,7
Считаю это оптимальным, так как при положительных температурах гораздоо чаще сотые играют роль чем при отрицательных. ИХМО. На вскидку - не придумал проекта где сотые в отрицательных значениях играют роль. При положительных - тот же инкубатор.
сотые ничего не играют. на них лучше не смотреть вообще. так что это не сущетсвенно хотя бы лично для меня
Плюс не выводится. Если без знака, то априори - положительное значение. Выводится будет 18,75 и -18,7
Считаю это оптимальным, так как при положительных температурах гораздоо чаще сотые играют роль чем при отрицательных. ИХМО. На вскидку - не придумал проекта где сотые в отрицательных значениях играют роль. При положительных - тот же инкубатор.
Неа, как птицевод говорю, не родилась еще та курица, которая свой терморежим с сотыми поддерживает. Десятые и те плюс минус.
так и сотым верить нельзя
Интересный момент получается.
Код из поста №47 при компиляции в памяти занимает:
Sketch uses 1 378 bytes (4%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
А перенеся основной код в функцию (добавив буквально пару строк) и оставив в основном цыкле 1 строку - вызов функции, при компиляции получаем уже:
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
т.е. в 2 раза больше от первоначального варианта. Получается - чем больше мы чистим код и переносим действий в функции (сокращая тем самым основное тело программы), тем больше места мы занимаем в памяти Дуни?
А что же будет, если функции перенести в библиотеки? Еще больше?
неа. ты что то намудрил. разница 6 байт
хотя может разница в том что ты используешь наверно версию 1.6.0, а я 1.0.6
поставь 1.0.6 и меньше проблемм у тебя будет
хотя может разница в том что ты используешь наверно версию 1.6.0, а я 1.0.6
поставь 1.0.6 и меньше проблемм у тебя будет
Наверное. У меня стоит 1.5.8
Проверил на версии 1.0.6
Размер скетча в двоичном коде: 2 782 байт (из 32 256 байт максимум)
В версии 1.6.0
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
jeka_tm, какая у Вас интересная модификация Arduino IDE. Подскажите, пожалуйста как себе сделать такую же? Где и какие плагины скачать или это как-то подругому делается?
тут гляньте: http://arduino.ru/forum/obshchii/novichkam-podskazki
jeka_tm, какая у Вас интересная модификация Arduino IDE. Подскажите, пожалуйста как себе сделать такую же? Где и какие плагины скачать или это как-то подругому делается?
просто внешний вид изменен
http://arduino.ru/forum/obshchii/novichkam-podskazki#comment-104199
Nemo вот один и второй код. проверь еще раз. хз что ты тестируешь
jeka_tm Да тот же код и тестирую. Вот что в версии 1.6.1 :
Sketch uses 2 772 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
Вот код:
Если не трудно, прогони у себя. Сам в шоке.
да где же он один и тотже)))
разговор шел просто перенести в функцию. про передачу значений разговора не было
2886 получается
а если передавать не float а int число и byte число знаков после запятой то остается как есть))
да где же он один и тотже)))
разговор шел просто перенести в функцию. про передачу значений разговора не было
2886 получается
а если передавать не float а int число и byte число знаков после запятой то остается как есть))
Ясно. Значит всё из за float...
Двумя переменным не хочу передавать, я ж с плавающей точкой все мучу. Поэтому передавать четко 2 знака после запятой не хотел. Передаю только 1 параметр, а внутри уже определяюсь с разрядами, минусами и т.д.
Но на мой вопрос вы ответили. Спасибо.
так можно тремя переменными. первая знак, вторая до запятой, треться после запятой
работа с float тяжелая для меги. при использовании автоматически используется математика, библиотка math кажется
так можно тремя переменными. первая знак, вторая до запятой, треться после запятой
Да. Но для этого нужно значение разкладывать на три переменные до вызова функции. А у меня получается вся работы выполняется уже внутри функции. А передаем только конкретное значение температуры. И в основном цыкле программы фигурирует только одна строка:
Я это делал для того делал, чтобы следующим шагом запихнуть две функции void ledDigitDisplay() и void Indicate() в библиотеку, тем самым минимизировать до самого небалуйся код основной программы.
На выходных - допишу, покажу что получиться.
ну тогда смирись что объем больше))) да и места вроде еще вагон остается
так можно тремя переменными. первая знак, вторая до запятой, треться после запятой
Да. Но для этого нужно значение разкладывать на три переменные до вызова функции. А у меня получается вся работы выполняется уже внутри функции. А передаем только конкретное значение температуры. И в основном цыкле программы фигурирует только одна строка:
Я это делал для того делал, чтобы следующим шагом запихнуть две функции void ledDigitDisplay() и void Indicate() в библиотеку, тем самым минимизировать до самого небалуйся код основной программы.
На выходных - допишу, покажу что получиться.
Жду с нетерпением! ))
Переделал код. В старом около-нулевые значения не корректно обрабатывались.
Да и код получился покороче. Хотя и по замороченей. По строкам - особо много не выиграл, но по размеру занимаемой памяти улучшения налицо. Гляньте, а лучше потестите, кто заинтересован. Возможно еще что-то упустил.
Sketch uses 1 536 bytes (4%) of program storage space. Maximum is 32 256 bytes.
Global variables use 45 bytes (2%) of dynamic memory, leaving 2 003 bytes for local variables. Maximum is 2 048 bytes.
Из минусов - перестал отображаться 0 в формате "0 градусов цельсия" как было в старой версии кода. Но подумав, не стал дописывать, так как все равно все остальные значения отображаются без знака градуса.
Пошел прикручивать датчик температуры.....
Переделал код. В старом около-нулевые значения не корректно обрабатывались.
Да и код получился покороче. Хотя и по замороченей.
Да я бы не сказал, что замороченней. По-моему наоборот, что-то понятное вырисовывается.
а почему не так? :)
Да я бы не сказал, что замороченней. По-моему наоборот, что-то понятное вырисовывается.
а почему не так? :)
Спасибо. Поправил.
Прикрутил датчик. С помощью своего кода и использованием библиотеки DallasTemperature.h не получилось пока. Взял предложенный jeka_tm код.
что то вроде этого должно быть. но это для 1 термодатчика. для нескольких надо поправить
Температуру выводит, но подмигивает немного. Нужно еще смотреть. Попробую код, предложенный bwn в 59 посту данной темы.
Вот в этом коде так сделано.
Чет с него улетает - 270 пост.
Правда там код длинный. Придется разбираться долго. Чужие коды мне сложно для чтения даются. Не программист я по жизни. Так. Любитель.
Да. Код забыл:
Два варианта:
1. Писать неблокирующий 1-Wire.
2. Вывод индикации делать в прерывании по таймеру, а в библиотеке OneWire убрать запрет прерываний.
Если код Жеки мигает, можете не возиться, у меня тот же самый.
Могу добавить к maksim, меряйте температуру с разумными интервалами 1-2 минуты и тогда станет практически незаметно. Это наверно самое простое.
Могу добавить к maksim, меряйте температуру с разумными интервалами 1-2 минуты и тогда станет практически незаметно. Это наверно самое простое.
Мне для этого часы нужно прикручивать? Или через паузу минуту отсчитывать?
Могу добавить к maksim, меряйте температуру с разумными интервалами 1-2 минуты и тогда станет практически незаметно. Это наверно самое простое.
Мне для этого часы нужно прикручивать? Или через паузу минуту отсчитывать?
Через millis().
Два варианта:
1. Писать неблокирующий 1-Wire.
2. Вывод индикации делать в прерывании по таймеру, а в библиотеке OneWire убрать запрет прерываний.
А можно подробнее? Просто край как необходимо разобраться. Все мои проекты с дуней связаны с датчиком ds18b20. Как это - неблокирующий 1-Wire? Читал что можно отправить запрос на измерение, потом продолжить индикацию, а после ответа от датчика уже обработать результат. Но как это реализовать - непонятно. Ткните носом пожалуйста куда посмотреть?
Через millis().
если в теории, мне нужно накопить минуту в переменной после запуска программы, затем измерить температуру, затем снова вернуться к накоплению минуты? А как быть с обнулением через 50 суток? И можно ли производить другие действия пока millis() будет минуту накапливать?
Читал что проблему мерцания через millis() решить можно. Только чет не пойму я этот оператор. Без параметров. Возвращает кол-во милисекунд с моментв выполнения текущей программы: т.е. с момента загрузки скетча в дуню или с момента включения уже загруженной дуни в сеть питания? А если она не выключалась? Работает круглосуточно? Сплошная каша.
Я тут подумал, если это возможно, выводимую переменную сделать как типа long которая запоминает последнее значение и ее обновлять уже датчиком, тоесть если не будет цифры с датчика то она покажет предыдущее значение, прокатит? )
Я тут подумал, если это возможно, выводимую переменную сделать как типа long которая запоминает последнее значение и ее обновлять уже датчиком, тоесть если не будет цифры с датчика то она покажет предыдущее значение, прокатит? )
Если я правильно понимаю, наша проблема с мерцанием именно в измерении датчика. Он меряет примерно 0,5 сек. на это время и происходит мигание. Т.е. если делать как вы предлагаете, то от измерения мы никуда не уходим. И сохранять его хоть в переменную, хоть сразу на вывод пускать, все равно теряем 0,5 сек. Да? Или я туплю?
Да, скорее всего мое предположение ошибочно
В обоих вариантах речь идет об использовании таймеров счетчиков.
Но для вашей задачи думаю есть еще и третий вариант - более равномерно пользоваться методами библиотеки OneWire при помощи конечного автомата. И да измерять раз в секунду температуру безссмысленно, более чем достаточно раз в 30 секунд.
Так же возможен и 4 вариант - просто оптимизировать код:
Если же все равно раз в 10 секунд будут мерцания, то возвращаемся к 3 варианту:
Nemo, Sirox, для начала прочтите это . Код который вам дал jeka_tm, уже убрал задержку на конвертацию и осталось только считывание данных. Разница между началом конвертации и считыванием, сделано с помощью millis(). Обнуление через 50 суток, приведет к одному пропуску считывания, дальше все пойдет по кругу.
Т.к. у maksim опыта намного больше моего, он вам предлагает более изящные, но и более сложные варианты. Чем воспользоватся в данном случае, решать вам. Мое предложение не убирает мерцание, а делает его более редким.
P/S к 97 посту это не относится.
maksim - Большое спасибо!
Попробовал оба кода. Оба работают без мерцания! Супер!
Не знаю, какой из них подойдет для моей затеи с несколькими датчиками, но для проекта с 1 датчиком и 1 индикатором - уже можно брать и работать. Готовый, рабочий код. (проверял правда пока только в положительном диапазоне температур).
А несколько датчиков - пока не смогу попробовать, так как даттчики есть, а шилд-индикатор только один. Нужно решить, то ли заказать еще (маловат сам индикатор в размерах), то ли докупить микросхем 74hс595 и напаять своих (индикаторы есть побольше в размере, правда с общим анодом). Подумаю, просчитаю что выгоднее по деньгам, тогда решу... Ну это позже.
Остальсь только разобраться в самом коде. А это посложнее будет... Можно я буду вопросы по коду задавать где непонятно?
Например:
1 ) - я правильно понял что размер задержки в первом коде (10 секунд) вы задаете единожды в строке номер 30, а во вторм коде - тоже единожды но уже 30 сек. в строке номер 75 ?
2) - я правильно понял что как сказал выше bwn в обоих случаях мы не убираем мерцание, а делаем его более редким (раз в 10 и 30 секунд соответственно)?
bwn - спасибо за ссылку и совет. Обязательно вникну. Давно хотел разобраться с этой millis()
p/s/ Для кого критично: по ресурсоемкости первый код чуть более легче чем второй. Не на много.
Sketch uses 3 030 bytes (9%) of program storage space. Maximum is 32 256 bytes.
Global variables use 50 bytes (2%) of dynamic memory, leaving 1 998 bytes for local variables. Maximum is 2 048 bytes.
Против
Sketch uses 3 092 bytes (9%) of program storage space. Maximum is 32 256 bytes.
Global variables use 65 bytes (3%) of dynamic memory, leaving 1 983 bytes for local variables. Maximum is 2 048 bytes.
Судя по тому, что у вас мерцание исчезло вовсе, дело было не в задержке от считывания с датчика, а в перерисовке дисплея. Соответственно код Жеки тоже рабочий, только надо было добавить интервал между измерениями. Во втором коде maksim-а вы упустили 48 строку, а она важная.
Погонять несколько датчиков можете и сейчас для тренировки - пожертвуйте знаком минус и выводите в этот разряд номер отображаемого датчика.
Также попробуйте понять, где грабли в первом коде maksim-а.