код программы амперметр с уставкой по току Код (C++): #include <EmonLib.h> #include <EEPROM.h> #define SCLK 13 // пины ардуины #define RCLK 10 #define DIO 11 #define button1 3 #define button2 4 #define button3 5 #define inport 7 #define PIN_RELAY 9 #define PIN_RELAYof 6 // Определяем пин, используемый для подключения реле #define led_pin 2 // Определяем пин, используемый для подключения реле EnergyMonitor emon1; unsigned long countR=0 ; byte digitBuffer[4]; int turns=0 ; int zero_level=512; unsigned int countT=0; byte menu=0; // назначаем пины кнопок bool pin_K1 = 0, pin_K2 = 0, pin_K3 = 0 ,pin_K7=0; bool enter=0; boolean s1=0,s2=0,s3=0; byte Flag_Tok=0; // Создаем переменные int address = 0; // Тут хранятся данные считанные из памяти byte tok=22; byte vremya=150; ISR(TIMER1_COMPA_vect) { cli(); showDisplay(); sei(); } ISR(TIMER0_COMPA_vect) { cli(); SB123(); sei(); } void setup() { emon1.current(0,111.1); //настройка амперметра pinMode(RCLK, OUTPUT); pinMode(SCLK, OUTPUT); pinMode(DIO, OUTPUT); Serial.begin(9600); //----------------- Инициализация пинов --------------------- pinMode (button1, INPUT_PULLUP); pinMode (button3, INPUT_PULLUP); pinMode (button2, INPUT_PULLUP); pinMode (inport, INPUT_PULLUP); pinMode(PIN_RELAY, OUTPUT); // Объявляем пин реле как выход pinMode(PIN_RELAYof, OUTPUT); pinMode(PIN_RELAY, OUTPUT); pinMode(led_pin, OUTPUT); // Объявляем пин реле как выход digitalWrite(PIN_RELAY, HIGH); // Выключаем реле - посылаем высокий сигнал digitalWrite(PIN_RELAYof, HIGH); digitalWrite(led_pin, HIGH); // инициализация Timer1 cli(); // отключить глобальные прерывания TCCR1A = 0; // установить регистры в 0 TCCR1B = 0; OCR1A =1250;// установка регистра совпадения TCCR1B |= (1 << WGM12); // включение в CTC режим // Установка битов CS10 и CS12 на коэффициент деления 1024 TCCR1B |= (1 << CS11); TCCR1B |= (1 << CS10); TIMSK1 |= (1 << OCIE1A); // включение прерываний по совпадению // инициализация Timer1 /**** настройка прерывания по таймеру каждую 0,001 сек (вызов функции ISR (TIMER0_COMPA_vect)) ****/ TCCR0A |= (1 << WGM01); //сброс при совпадении OCR0A = 255; //начало отсчета до переполнения (249) TIMSK0 |= (1 << OCIE0A); //разрешить прерывание при совпадении с регистром А TCCR0B |= (1 << CS01) | (1 << CS00); //установить делитель частоты на 64 sei(); //разрешить прерывания tok = EEPROM.read(1); vremya = EEPROM.read(0); digitBuffer[0] =12; digitBuffer[1] =12; digitBuffer[2] =12; digitBuffer[3] =12; } void loop(){ //if(pin_K7==0 && countR!=10){ countR=countR+1;}else{countR=0;} // if(countR==10){digitalWrite(PIN_RELAYof, LOW);countR=0;} if(enter==0){menu0();} //функция кнопок переключение первой ветки меню если переменная menu меньше 10 //Serial.println(countR); //............................................................................................................. switch (menu)//переключатель первой ветки меню меню { case 0: { double Irms = emon1.calcIrms(1480); // Calculate Irms only //if(Irms<0.31){Irms=0;} if(Irms>tok){ digitalWrite(led_pin, LOW); Flag_Tok=1; }else{ digitalWrite(led_pin, HIGH); Flag_Tok=0; } /*/ if( Flag_Tok>0){countT++;} if(Flag_Tok<1 and countT>0){countT=countT-1;} if(countT==vremya){countT=0; while(1){ digitalWrite( PIN_RELAY,LOW);}}/*/ turns=Irms; //Serial.println(countT); //Serial.println(Flag_Tok); //Serial.println(Irms); /*/ if (turns<1 && turns>0) {turns=turns*100; cli(); digitBuffer[0] =12; digitBuffer[1] =13; digitBuffer[2] =turns/10; digitBuffer[3] =turns- digitBuffer[2]*10; //формула отображения переменной sei(); } else { cli(); digitBuffer[0] =turns/1000; digitBuffer[1] =turns/100- digitBuffer[0]*10; digitBuffer[2] =turns/10- digitBuffer[1]*10-digitBuffer[0]*100; digitBuffer[3] =turns- digitBuffer[2]*10-digitBuffer[1]*100-digitBuffer[0]*1000; //формула отображения переменной if(digitBuffer[2]==0 && digitBuffer[1]==0 && digitBuffer[0]==0 ){digitBuffer[2] =12;} if(digitBuffer[1]==0 && digitBuffer[0]==0 ){digitBuffer[1] =12;} if(digitBuffer[0]==0 ){digitBuffer[0] =12;} sei(); break; /*/ cli(); digitBuffer[0] =turns/1000; digitBuffer[1] =turns/100- digitBuffer[0]*10; digitBuffer[2] =turns/10- digitBuffer[1]*10-digitBuffer[0]*100; digitBuffer[3] =turns- digitBuffer[2]*10-digitBuffer[1]*100-digitBuffer[0]*1000; //формула отображения переменной if(digitBuffer[2]==0 && digitBuffer[1]==0 && digitBuffer[0]==0 ){digitBuffer[2] =12;} if(digitBuffer[1]==0 && digitBuffer[0]==0 ){digitBuffer[1] =12;} if(digitBuffer[0]==0 ){digitBuffer[0] =12;} sei(); break; } //............................................................................................................. case 1: ///выбор параметра A { enterKN(); //кнопка ввод if(enter==0){digitBuffer[0] =10; //формула отображения символа параметра digitBuffer[1] =12; digitBuffer[2] =12; digitBuffer[3] =12;} if(enter==1 ){ while(1){nastroyka1(); enterKN(); if(enter==0){ EEPROM_SAVE(); break; } } } break; } //.............................................................................................. case 2: ///выбор параметра P { enterKN(); //кнопка ввод if(enter==0){ digitBuffer[0] =11; digitBuffer[1] =12; digitBuffer[2] =12; digitBuffer[3] =12;} if(enter==1 ){ while(1){nastroyka1(); enterKN(); if(enter==0){ EEPROM_SAVE();break; } } } break; } } } void showDisplay() { const byte digit[14] = { // маска для 7 сигментного индикатора 0b11000000, // 0 0b11111001, // 1 0b10100100, // 2 0b10110000, // 3 0b10011001, // 4 0b10010010, // 5 0b10000010, // 6 0b11111000, // 7 0b10000000, // 8 0b10010000, // 9 0b10001000, //A10 0b10001100, //P11 0b11111111, // 12 пусто 0b01000000, // 13 ноль с точкой }; const byte chr[4] = { // маска для разряда 0b00001000, 0b00000100, 0b00000010, 0b00000001 }; // отправляем в цикле по два байта в сдвиговые регистры for(byte i = 0; i <= 3; i++){ digitalWrite(RCLK, LOW); // открываем защелку shiftOut(DIO, SCLK, MSBFIRST, digit[digitBuffer[i]]); // отправляем байт с "числом" shiftOut(DIO, SCLK, MSBFIRST, chr[i]); // включаем разряд digitalWrite(RCLK, HIGH); // защелкиваем регистры delayMicroseconds(500); } } void SB123() { if( digitalRead(button1) == LOW ){pin_K1 =1;} else {pin_K1 =0;} if( digitalRead(button2) == LOW ){pin_K2 =1;} else {pin_K2 =0;} if( digitalRead(button3) == LOW ){pin_K3 =1;} else {pin_K3 =0;} if(digitalRead(inport)==LOW){pin_K7 =1;} else {pin_K7 =0;} } void menu0() { if(pin_K1==1){ s1=1;} if(s1==1){ if(pin_K1==0){ s1=0;menu=menu+1; if(menu>2){menu=0;}}} if(pin_K3==1){ s3=1;} if(s3==1){ if(pin_K3==0){ s3=0;menu=menu-1; if(menu==255){menu=2;}}} } void enterKN() { if(enter==1){ if(pin_K2==1){ s2=1;}if(s2==1){ if(pin_K2==0){ s2=0;enter=0; }} } else{ if(pin_K2==1){ s2=1;}if(s2==1){ if(pin_K2==0){ s2=0;enter=1; }}} } void nastroyka1() { SB123(); switch (menu)//переключатель первой ветки меню меню {{ case 1: turns=tok; break; } { case 2: turns=vremya; break; }} digitBuffer[0] =turns/1000; digitBuffer[1] =turns/100- digitBuffer[0]*10; digitBuffer[2] =turns/10- digitBuffer[1]*10-digitBuffer[0]*100; digitBuffer[3] =turns- digitBuffer[2]*10-digitBuffer[1]*100-digitBuffer[0]*1000; if(pin_K1==1){ s1=1;} if(s1==1){ if(pin_K1==0){ s1=0;turns=turns+1; if(turns>500){turns=0;}}} if(pin_K3==1){ s3=1;} if(s3==1){ if(pin_K3==0){ s3=0;turns=turns-1; if(turns<0){turns=500;}}} switch (menu)//переключатель первой ветки меню меню {{ case 1: tok=turns; break; } { case 2: vremya=turns; break; }} } // Функция записи данных в Энергонезовисимую память EEPROM void EEPROM_SAVE(){ EEPROM.write(1,tok); EEPROM.update(0,vremya); } void nastroyka2() { SB123(); digitBuffer[0] =vremya/1000; digitBuffer[1] =vremya/100- digitBuffer[0]*10; digitBuffer[2] =vremya/10- digitBuffer[1]*10-digitBuffer[0]*100; digitBuffer[3] =vremya- digitBuffer[2]*10-digitBuffer[1]*100-digitBuffer[0]*1000; if(pin_K1==1){ s1=1;} if(s1==1){ if(pin_K1==0){ s1=0;vremya=vremya+1; if(vremya>500){vremya=0;}}} if(pin_K3==1){ s3=1;} if(s3==1){ if(pin_K3==0){ s3=0;vremya=vremya-1; if(vremya<0){vremya=500;}}} } Переменная tok выставляю 22, сохраняется все работает какое то время затем она принемает значение 12 сама по себе!! Кто ни будь сталкивался с подобными проблемами ?
А зачем здесь EEPROM? Переменная tok перезаписывается здесь: Код (Text): switch (menu)//переключатель первой ветки меню меню {{ case 1: tok=turns; break; } { case 2: vremya=turns; break; }} Это не причина?
Вы в курсе, что ресурс ЕЕПРОМ - всего 100 тыс записей? Вы пишете в ЕЕПРОМ при каждом проходе loop(), насколько я вижу. При таком подходе вы протрете дыру в памяти за полчаса, а потом ЕЕПРОм просто сдохнет .- что видимо у вас уже и произошло.
ВСе понятно надо turs заменить она приравнивается IRMS он та как раз 12 ампер там update на этот случай, и туда заходит только при настройке ,а она редко меняется, по крайней мере я на это расчитываю
Не всегда железо виновато бывают еще электрики в своем коде путаются я поменял сам было до создания темы Код (C++): // Функция записи данных в Энергонезовисимую память EEPROM void EEPROM_SAVE(){ EEPROM.update(1,tok); EEPROM.update(0,vremya); } надеюсь все заработает Код (C++): SB123(); int disp; switch (menu)//переключатель первой ветки меню меню {{ case 1: disp=tok; break; } { case 2: disp=vremya; break; }} digitBuffer[0] =disp/1000; digitBuffer[1] =disp/100- digitBuffer[0]*10; digitBuffer[2] =disp/10- digitBuffer[1]*10-digitBuffer[0]*100; digitBuffer[3] =disp- digitBuffer[2]*10-digitBuffer[1]*100-digitBuffer[0]*1000; if(pin_K1==1){ s1=1;} if(s1==1){ if(pin_K1==0){ s1=0;disp=disp+1; if(disp>500){disp=0;}}} if(pin_K3==1){ s3=1;} if(s3==1){ if(pin_K3==0){ s3=0;disp=disp-1; if(disp<0){disp=500;}}} switch (menu)//переключатель первой ветки меню меню {{ case 1: tok=disp; break; } { case 2: vremya=disp; break; }} А протеус проект можно выкладывать?
Да ради бога. Там и схема и прошивка. Кому надо испытают. Только не забудьте про библиотеки, потому как не каждому владельцу протеуса нужны элементы типа ардуины.
Все есть только я не совсем понял как архив скинуть Вин пар архив хотел отправить через загрузить файл, это на будущее чтоб знать Мне недал сервер загрузить написал что нельзя этот файл загрузить
Архивы .rar не пускаем, у них дыры в безопасности. Ну и уважайте тех, у кого нет WinRAR чтобы распаковать. Архивы можно в ZIP, написано же
А вообще RAR надо похоронить как таковой. Его даже Linux игнорирует как таковой, потому как не всё, что реклама это гуд. Он (Linux) поддерживает unrar, но работать с ним не рекомендовано. И держать только если надо открывать чужой файл типа rar.
zip тоже весь патентами обложен, из-за чего на многих сайтах проблемы с jpeg (который использует zip для сжатия)
Вот именно на это я и намекал, говоря, чтобы о других подумали. Я не хочу ничего такого ставить, мне zip и tar хватает
Ватметр электросчетчик успешно запустился и не только у меня их всего будет 70 так что в дальнейшем о проблеме прошивок , если будут, отпишусь