int latchPin = 8; //Пин "защелки" первого регистра подключен к ST_CP (RCLK)входу первого регистра отвечающего за сегменты
int clockPin = 12; //Пин подключен к SH_CP входу 74HC595 (SCLK)
int dataPin = 11; //Пин подключен к DS входу 74HC595 (DIO)
int TimeLight = 5; //время для разогрева сегментов
byte SegDisplay; // переменная для вывода символов на индикаторе
byte RazrDisplay; // переменная для включения разрядов
int sensorPin=A0;
// Настройка комбинации для отображения каждого номера на дисплее.
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] = {8, 4, 2, 1}; //массив цифр, указывающий разряды
void setup() {
Serial.begin(9600);
// обозначаем все пины как выходы
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
int tem = 0;
int raw = analogRead(sensorPin);
float val2 = (raw/1023.0 )*5.0*1000/10;
Serial.println(val2);
tem = 999;
float temperature = val2; // Можете подставить любые значения. Следите чтобы стояла именно . (например 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, RazrDisplay); // Записываем информацию для первого регистра (Номер разряда)
shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для второго регистра (Номер символа)
digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}
При использования этого кода показания аналогового датчика LM35 некорректно выводятся.
хотя при простом выводе показаний датчика в серийный порт, правильно.
Для начала закомментировать весь loop, затем просто выводить разные числа и смотреть что получается. Скорее всего будет бардак. Разобраться с динамической индикацией и добиться нормального отображения. Только после этого переходить к отображению показаний. Если опять ерунда будет проверить пересчёт значений.
Помогите разобраться.
При использования этого кода показания аналогового датчика LM35 некорректно выводятся.
хотя при простом выводе показаний датчика в серийный порт, правильно.
"некорректно" - это как?
Вообще, судя по комментариям в коде - писал какой-то школьник... код помойка, проще переписать, чем копаться в ней.
одно разбиение числа на разряды аж 60 строчек... когда реально достаточно 4-6 строк
Для начала закомментировать весь loop, затем просто выводить разные числа и смотреть что получается. Скорее всего будет бардак. Разобраться с динамической индикацией и добиться нормального отображения. Только после этого переходить к отображению показаний. Если опять ерунда будет проверить пересчёт значений.