Вольтметр с 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 вольта не требовалась). Лады, спорить не будем. Нет смысла.