Вольтметр с 7seg и MAX7219
- Войдите на сайт для отправки комментариев
Пытаюсь извернуться с выводом измеренного напряжения на 7 сегментный индикатор. Как вывести число с плавающей точкой не разобрался и решил перемножить все до целых чисел и управлять точкой по условию. Вроде даже все получилось, но если изменить разрядность с 10 бит(1023) на 11, 12..16 - показания уплывают и глаз уже замылился окончательно, не могу понять куда копать.
Моделирую все в протеусе. В итоге планируется ацп ADS1115, который на 16 бит, но его макроса не нашел, потому решил с обычным входом протестить, а потом уже с большей точностью, ну вот на этом все и посыпалось. Хочу разобраться что не так или может найти рабочий способ выводить float на 7 сегментный индикатор. Гуглил и не нагуглил. Помогите
/* #define NUMBEROFDRIVERS 1 <- Change this number PINOUT: MODULE.....UNO/NANO.....MEGA VCC........+5V..........+5V GND........GND..........GND DIN........11...........51 CS (LOAD)..10...........10 CLK........13...........52 /* Include the HCMAX7219 and SPI library */ #include <HCMAX7219.h> #include "SPI.h" #define LOAD 10 HCMAX7219 HCMAX7219(LOAD); int u = 0; // переменная для числа преобразования 0-1023 //unsigned int u_in = 0; // переменная для напряжения float u_in = 0.0; void setup() { pinMode(A0,INPUT);// A0 - аналоговый вход //Serial.begin (9600); } /* Main program */ void loop() { u = analogRead(A0); // измерение по входу А0 u_in = ((u * 49.99999999999) / 1023) *1000; // пересчет измерения в вольты (на Uвх = 5 В) delay(20); if (u_in<=100) { HCMAX7219.Clear(); HCMAX7219.print7Seg("O",4); HCMAX7219.print7Seg("O",3,3); //HCMAX7219.Refresh(); HCMAX7219.print7Seg(u_in,2); HCMAX7219.Refresh(); while(1); delay(10);} if (u_in>100&&u_in<1000){ HCMAX7219.Clear(); HCMAX7219.print7Seg("0",3,4); HCMAX7219.print7Seg(u_in,3); // Send the output buffer to the display // HCMAX7219.Refresh(); while(1); delay(10);} if (u_in>1000&&u_in<10000){ HCMAX7219.Clear(); HCMAX7219.print7Seg(u_in,3,4); // Send the output buffer to the display // HCMAX7219.Refresh(); while(1); delay(10);} else if (u_in>10000){ HCMAX7219.Clear(); HCMAX7219.print7Seg(u_in,3,4); HCMAX7219.Refresh(); while(1); delay(10);} }
35 строка не ясна ! умножили на 10 (49.9999 вместо 4.9999) потом еще на 1000
А с чего ты решил, что в ацп больше 10 бит?
49.9999 - представил пересчет после делителя на 10, (вообще конечно должно быть ровно 50, но с целым отказывался работать по неясной причине), умножил на 1000 чтобы гарантировано избавиться от запятой..
rkit, https://radiolaba.ru/microcotrollers/ads1115-opisanie-i-podklyuchenie-16-bitnogo-atsp.html
Надо не 50, а 50.0 тогда уж.
согласен, работает, но основная проблема остается...
Как то не аккуратненько.
согласен, работает, но основная проблема остается...
в чем проблема-то?
Вообще то правильней значение АЦП переводить в напряжение так
u_in = Vref / 1024 * (ADC + 0.5); //Vref = 5 В в вашем случае
Это если Vref с плавающей точкой.
рабочий способ выводить float на 7 сегментный индикатор
А если вообще отказаться от флоат? Штука медленная, жручая в смысле памяти. Может, через оператор "map" масштабировать данные аналогового входа (0-1023), скажем, в милливольты (0-5000). Спокойно и без флоатовских изысков работаем с переменной типа int. А децимальную точку просто поставить в левом разряде навсегда.
PS: Друзья, я ничего не ляпнул криминального по своему обыкновению?
Ляпнул ... у ТС делитель еще 10:1 и целых разрядов до двух ...
у ТС делитель еще 10:1 и целых разрядов до двух ...
Ну и что? Принцип-то остается. Только расположение точки будет меняться в зависимости от величины измеренного напряжения. Пара строчек в скетче. И только.
Вот он и нагородил там ради положения точки - портянку, а воз и ныне там ...
А если вообще отказаться от флоат? Штука медленная, жручая в смысле памяти. Может, через оператор "map" масштабировать данные
можно и отказаться, только не совсем не так, как вы пишете. Зачем чего-то масштабировать с помощью MAP, если и АЦП ардуины, и ADS1115 - сразу выдают результат в целых числах?
ТС куда-то пропал и не отвечает... он так и не обьяснил, в чем вообще проблема вывести любое число (что целое. что флоат) - на индикатор? В инете куча примеров разбиения числа на разряды... А может ТС уже давно все решил. а мы тут спорим.
ТС вроде как так и хочет. Я все формулы привёл. Минимум - минимор, без флоатов и мапов. Только точку рисуй.
А если вообще отказаться от флоат? Штука медленная, жручая в смысле памяти. Может, через оператор "map" масштабировать данные
можно и отказаться, только не совсем не так, как вы пишете. Зачем чего-то масштабировать с помощью MAP, если и АЦП ардуины, и ADS1115 - сразу выдают результат в целых числах?
Немного смутила у ТС 35-я строчка: "
((u * 49.99999999999) / 1023) *1000;
" То есть, входные цифры (целые, дробные...) делить на 1023, умножать на 1000 и априри получать дробное число. МАР это делает изящнее (уверен, что точность до 1/1000 вольта не требовалась). Лады, спорить не будем. Нет смысла.