Несколько TM1637. Общая процедура вывода информации
- Войдите на сайт для отправки комментариев
Чт, 17/01/2019 - 22:45
Всем доброго!
Вопрос навеян этой темой.
В устройстве будет 3 индикатора TM1637. В топике есть обычный вариант применения:
01 |
#include "TM1637.h" // Подключаем библиотеку |
02 |
#define CLK_1 8 // первый семисегмент |
03 |
#define DIO_1 9 // |
04 |
#define CLK_2 10 // второй семисегмент |
05 |
#define DIO_2 11 // |
06 |
TM1637 disp_1(CLK_1, DIO_1); |
07 |
TM1637 disp_2(CLK_2, DIO_2); |
08 |
void setup() { |
09 |
disp_1.set(7); |
10 |
//disp_1.init(D4056A); |
11 |
disp_2.set(7); |
12 |
//disp_2.init(D4056A); |
13 |
} |
14 |
15 |
void loop() |
16 |
{ |
17 |
disp_1.display(1234); |
18 |
delay(2000); |
19 |
disp_2.display(5678); |
20 |
delay(2000); |
21 |
} |
Хотелось бы написать одну процедуру вывода на индикатор, где аргументом будет этот самый индикатор.
Подскажите, плс: как передать нужный дисплей в процедуру вывода (какой это тип данных)?
Как пример:
15 |
void out_disp(disp) |
16 |
{ |
17 |
disp.display(1234); |
18 |
delay(2000); |
19 |
disp.display(5678); |
20 |
delay(2000); |
21 |
} |
Возможно такое?
Спасибо.
Возможно. Надо в функцию передавать указатель на класс. Примерно так:
void out_disp(TM1637 * disp) { disp->display(1234); delay(2000); disp->display(5678); delay(2000); } //Пишем в первый дисплей out_disp(&disp_1); //Пишем во второй дисплей out_disp(&disp_2);void out_disp(TM1637 * disp)
{ disp->display(1234); delay(2000); disp->display(5678); delay(2000); }если уж ты проверку на NULL не делаешь, то передавать надо ссылку
void out_disp(const TM1637 &disp) { disp.display(1234); delay(2000); disp.display(5678); delay(2000); } out_disp(disp1); out_disp(disp2);voidout_disp(constTM1637 &disp)то ошибка:voidout_disp(uint8_tTM1637 &disp)Приведите полностью ваш скетч и целиком сообщение об ошибке
Всем спасибо! Разобрался.
Вот рабочий вариант:
#include "TM1637.h" #define CLK 9//Pins for TM1637 #define DIO 8//Pins for TM1637 TM1637 disp_1(CLK,DIO); void out_disp(TM1637 &disp) { disp.display(1234); delay(2000); disp.display(5678); delay(2000); } void setup() { disp_1.init(); disp_1.set(BRIGHT_TYPICAL); } void loop() { out_disp(disp_1); }Нальёшь при случае :)
Наливаю. Вот рабочий вариант подключения нескольких TM1637.
Таймер CLK подается на все одновременно. Сигнальный DIO - для каждого свой.
#include "TM1637.h" #define CLK 9//Pins for TM1637 #1 & #2 #define DIO 8//Pins for TM1637 #1 #define DIO2 10//Pins for TM1637 #2 TM1637 disp_1(CLK,DIO); TM1637 disp_2(CLK,DIO2); void out_disp(TM1637 &disp) { disp.display(1234); delay(2000); disp.display(5678); delay(2000); } void setup() { disp_1.init(); disp_1.set(BRIGHT_TYPICAL); disp_2.init(); disp_2.set(BRIGHT_TYPICAL); } void loop() { out_disp(disp_1); out_disp(disp_2); }Можете помочь чайнику, видимо пенсию не зря назначают, перерыл весь инет и не нашел как вывести десятичные данные на ТМ1637. Думаю что нужно вставить строку "displayInt(value) - вывести на экран четырёхзначное число" Сделал вольтметр на 220В, в монитор порта выводит напряжение, а на индикатор не получается. Будет у Вас время посмотреть код.
А где код то?
/*Подключаем библиотеку*/ #include "TM1637.h" #define CLK 3 //Pins for TM1637 #define DIO 2 //Pins for TM1637 TM1637 tm1637(CLK, DIO); /* переменные работающие в обработчике прерывания */ volatile int Umass_A[101]; //масив переменных для хранения мгновенных напряжений фазы А int Ucor = 0; long Uism_A = 0; // переменная для хранения измеренного напряжения и квадрата фазы А long Usumm_A = 0; // переменная для хранения сумм квадратов фазы А volatile byte counter = 0; // счетчик в обработчике прерывания int ADC0 = 0; // аналоговый вход 0 для переменной Ucor! int ADC1 = 1; // аналоговый вход фазы А #define ADC1 1 volatile byte flag = 0; /* переменные для усреднения напряжений*/ float sqrtUsum_A = 0; int real_U_A = 0; float coff = 0.138; //0.138 коэф для получения 220V unsigned long timeOut = 0;// переменная для хранения времени!!! void setup() { //Инициализация модуля tm1637.init(); tm1637.set(BRIGHT_TYPICAL); //BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7 0-7; delay(1500); //Delay TIMSK2 = 0b00000000; // запрещение прерывания по совпадению таймера/счетчика Т2 TCCR2A = 0b00000010; // режим работы СТС TCCR2B = 0b00000011; // предделитель на 32 ASSR &= ~(1<<AS2); // Выбор источника синхронизации таймера(от системного генератора OCR2A = 98; // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз за секунду ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); ADCSRA = 0b10000111; Serial.begin(9600); } void loop() { if(millis()-timeOut > 400) { timeOut = millis(); metod(); } if(flag == 3) { for ( int i = 1; i<101; i++) { Uism_A = Umass_A [i]; Uism_A -= Ucor;// убираем подьем синусоиды на 2 вольт Uism_A *= Uism_A; Usumm_A += Uism_A; } sqrtUsum_A = sqrt(Usumm_A); //вычисляем квадратный корень из суммы квадратов real_U_A = coff * sqrtUsum_A; //вычисляем реальное напряжение для фазы А Usumm_A = 0; counter = 0; flag = 0; Serial.println(real_U_A); //вывод напряжения 220 tm1637.point(false); //Задание на выключение разделителя int digitoneV = real_U_A/100; // После деления на 100 остаётся разряд сотен. int digittwoV = real_U_A/10; // Выделяем разряд. десятков. int digitfriV = real_U_A*10; // Выделяем разряд едениц. //Выводим массив на дисплей tm1637.display(1, digitoneV); tm1637.display(2, digittwoV); tm1637.display(3, digitfriV); tm1637.display(4, 28); // U //Задержка delay(1000); } } void metod() { Ucor = analogRead(ADC0); TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание while(flag<3); TIMSK2 = 0b00000000; // останавливаем таймер } word read_adc(byte adc_input) { ADMUX = adc_input | (ADMUX & 0xF0); //задержка для стабилизации входного напряжения ADCSRA |= (1<<ADSC); //начинаем преобразование (ADSC = 1) while((ADCSRA & 0x10)==0); //ждем, пока АЦП закончит преобразование (ADIF = 0) ADCSRA|=0x10;//устанавливаем ADIF return ADCW;//ADCW - содержит ADCH и ADCL как нам нужно //****************обработчик прерывания******************** ISR(TIMER2_COMPA_vect) { counter++; if((counter<= 100)&&flag == 0) { Umass_A[counter] = read_adc(ADC1); if(counter == 100) { flag = 3; counter = 1; } } }1
вставьте код по правилам форума, без этого никто помогать не станет
Всё получилось, помогли добрые люди.
/*Подключаем библиотеку*/ #include "TM1637.h" /*Определяем пины подключения*/ #define CLK 3 #define DIO 2 TM1637 tm1637(CLK, DIO); /* переменные работающие в обработчике прерывания */ volatile int Umass_A[101]; //масив переменных для хранения мгновенных напряжений фазы А int Ucor = 0; long Uism_A = 0; // переменная для хранения измеренного напряжения и квадрата фазы А long Usumm_A = 0; // переменная для хранения сумм квадратов фазы А volatile byte counter = 0; // счетчик в обработчике прерывания int ADC0 = 0; // аналоговый вход 0 для переменной Ucor! int ADC1 = 1; #define ADC1 1 volatile byte flag = 0; /* переменные для усреднения напряжений*/ float sqrtUsum_A = 0; int real_U_A = 0; float coff = 0.138; unsigned long timeOut = 0;// переменная для хранения времени!!! void setup() { /*Инициализация дисплея*/ tm1637.init(); tm1637.set(BRIGHT_TYPICAL); TIMSK2 = 0b00000000; // запрещение прерывания по совпадению таймера/счетчика Т2 TCCR2A = 0b00000010; // режим работы СТС TCCR2B = 0b00000011; // предделитель на 32 ASSR &= ~(1<<AS2); // Выбор источника синхронизации таймера(от системного генератора OCR2A = 98; // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз за секунду ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); ADCSRA = 0b10000111; Serial.begin(9600); } void loop() { if(millis()-timeOut > 400) { timeOut = millis(); metod(); } if(flag == 3) { for ( int i = 1; i<101; i++) { Uism_A = Umass_A [i]; Uism_A -= Ucor;// убираем подьем синусоиды на 2 вольт Uism_A *= Uism_A; Usumm_A += Uism_A; } sqrtUsum_A = sqrt(Usumm_A); //вычисляем квадратный корень из суммы квадратов real_U_A = coff * sqrtUsum_A; //вычисляем реальное напряжение для фазы А Usumm_A = 0; counter = 0; flag = 0; Serial.println(real_U_A); /*Вывод чисел массива на дисплей*/ int digitV = real_U_A/1000; // После деления на 1000 остаётся разряд тысяч. int digitoneV = real_U_A/100%10; // После деления на 100 остаётся разряд сотен. int digittwoV = real_U_A/10%10; // Выделяем разряд. десятков. int digitfriV = real_U_A%10; // Выделяем разряд единиц. //Выводим массив на дисплей tm1637.display(0, digitV); tm1637.display(1, digitoneV); tm1637.display(2, digittwoV); tm1637.display(3, digitfriV); delay(1000); } } void metod() { Ucor = analogRead(ADC0); TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание while(flag<3); TIMSK2 = 0b00000000; // останавливаем таймер } word read_adc(byte adc_input) { ADMUX = adc_input | (ADMUX & 0xF0);//задержка для стабилизации входного напряжения //начинаем преобразование (ADSC = 1) ADCSRA |= (1<<ADSC); while((ADCSRA & 0x10)==0); //ждем, пока АЦП закончит преобразование (ADIF = 0) ADCSRA|=0x10;//устанавливаем ADIF return ADCW;//ADCW - содержит ADCH и ADCL как нам нужно } //****************обработчик прерывания******************** ISR(TIMER2_COMPA_vect) { counter++; if((counter<= 100)&&flag == 0) { Umass_A[counter] = read_adc(ADC1); if(counter == 100) { flag = 3; counter = 1; } } }