дебажим гроб
- Войдите на сайт для отправки комментариев
Моей главной ошибкой, с переходом на ArduinoISP и самопальные платы, был отказ от сериала. Теперь каждый раз, устанавливая плату в какую-нибудь автоматически хрюкающую роботизированную чушку, я понятия не имею, что там происходит...
Вместо эпиграфа
Сап, народ, и доброго времени суток тебе. Задача (алгоритм) такова: есть каменный ящик, типа гроб. На самом деле он из профилей, гипсокартона и снаружи только раскрашен под камень, но неважно. У него есть ручка, которую можно крутить, фоторезистор, в который можно светить, и сбоку лежат угли, которые можно раздувать. Угли можно считать кнопкой, там подпружиненная пластинка, сдуваемая воздухом из меха. Каких-то особенных исполнительных устройств нет, кроме движка, открывающего крышку. Он работает нормально. Всё остальное сообщается по радио, другим устройствам.
Единственная нерабочая вещь здесь - энкодер. Его код был взят из стандартной библиотеки encoder, оба провода поддерживают прерывания (d2, d3). Работало в примере, в котором был только он и 12 В лента (коммутируемая полевиком). Далее он как-то отошёл на второй план, и сейчас безнадёжно упущен момент, когда же он перестал работать. Внятно причину этого я назвать не могу, необходимо её найти. Мб кто-то знает, что может конфликтовать с ним.
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Encoder.h> Encoder myEnc(3,2); RF24 radio(8,9); byte data[4]; const byte loga[64]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,18,22,25,28,29,30,33,36,39,42,46,49,53,56,60,64,68,72, 77,81,86,90,95,100,105,110,116,121,127,132,138,144,150,156,163,169,176,182,189,196,203,210,218,225,233,240,248,255}; const uint64_t pipes[2] = { 0xFFFFFFFF00LL, 0xFFFFFFFF01LL }; boolean flag_ir[3]={0,0,0}, flag_match[4]={0,0,0,0}, flag_open=0, flag_secret=0, flag_coals=0, blowflag=0; byte counter[3]={0,0,0}, countRecv=0, posFlag=0, oldFlag=0, light_next=0, light_lev=0, light_side_lev=0, coal_delta=0, coal_level=0; long oldPosition=0; unsigned long timestamp[7]; void setup(){ pinMode(A5,INPUT); // light sens pinMode(6,OUTPUT); // light out pinMode(7,INPUT_PULLUP); // coal sens pinMode(5,OUTPUT); // coal light pinMode(0,OUTPUT); // coffin door go pinMode(1,OUTPUT); // reverse pinMode(4,INPUT_PULLUP); // close endswitch pinMode(A3,INPUT_PULLUP); // open endswitch pinMode(A2,INPUT); // IR vases pinMode(A1,INPUT); pinMode(A0,INPUT); pinMode(A7,INPUT); pinMode(10,OUTPUT); // LED strip timestamp[0]=millis(); // IR0 timestamp[1]=timestamp[0]; // IR1 timestamp[2]=timestamp[0]; // IR2 timestamp[3]=timestamp[0]; // IRMatch timestamp[4]=timestamp[0]; // encoder timestamp[5]=timestamp[0]; // last_radio timestamp[6]=timestamp[0]; // side light timestamp[7]=timestamp[0]; // coal report timestamp[8]=timestamp[0]; // coal up timestamp[9]=timestamp[0]; // coal down radio.begin(); radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_MAX); radio.setChannel(1); radio.setRetries(15,15); radio.setPayloadSize(4); radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1,pipes[0]); radio.startListening(); } void loop(){ long newPosition=myEnc.read(); // -- Encoder --------------------------------------------- if(newPosition!=oldPosition){ oldPosition = newPosition; msgCentral(20,(byte) newPosition); } // updateFlag(3); if(posFlag==0 && oldPosition==240) updateFlag(1); // #0: 3 to right // if(posFlag==1 && oldPosition>248) resetFlag(); // overrotate 1 if(posFlag==1 && oldPosition>260) resetFlag(); // overrotate 1 if(posFlag==1 && oldPosition==80) updateFlag(2); // #1: 2 to left // if(posFlag==2 && oldPosition<72) resetFlag(); // overrotate 2 if(posFlag==2 && oldPosition<60) resetFlag(); // overrotate 2 if(posFlag==2 && oldPosition==160) updateFlag(3); // #2: 1 to right // if(posFlag==3 && oldPosition>180) resetFlag(); // overrotate 3 if(posFlag==3 && oldPosition>168) resetFlag(); // overrotate 3 if(posFlag==3 && oldPosition==0) updateFlag(4); // #3: 2 to left // if(posFlag==4 && oldPosition<-8) resetFlag(); // overrotate 4 if(posFlag==4 && oldPosition<-20) resetFlag(); // overrotate 4 if(posFlag==4 && oldPosition==160) updateFlag(5); // #4: 2 to right if(posFlag==5) coffinOpen(); // -- Modify light level ---------------------------------- if(millis()-timestamp[4]>=150 && light_lev<light_next){ light_lev++; timestamp[4]=millis(); } if(millis()-timestamp[4]>=50 && light_lev>light_next){ light_lev--; timestamp[4]=millis(); } analogWrite(10,light_lev); // analogWrite(10,loga[light_lev]); // -- Enable ---------------------------------------------- if(!digitalRead(A2)){ if(!flag_match[0] && counter[0]>104 && counter[0]<115){ // 99k flag_match[0]=1; timestamp[3]=millis(); msgCentral(1,1); // coffin IR0 } counter[0]=0; timestamp[0]=millis(); flag_ir[0]=1; } if(!digitalRead(A1)){ if(!flag_match[1] && counter[1]>65 && counter[1]<74){ // 66k flag_match[1]=1; timestamp[3]=millis(); msgCentral(2,1); // coffin IR1 } counter[1]=0; timestamp[1]=millis(); flag_ir[1]=1; } if(!digitalRead(A0)){ if(!flag_match[2] && counter[2]>35 && counter[2]<44){ // 33k flag_match[2]=1; timestamp[3]=millis(); msgCentral(3,1); // coffin IR2 } counter[2]=0; timestamp[2]=millis(); flag_ir[2]=1; } if(!flag_match[3] && analogRead(A7)<100){ flag_match[3]=1; msgCentral(4,1); // coffin IR3 } // -- Counter --------------------------------------------- if(millis()-timestamp[0]>=100 && flag_ir[0]){ counter[0]++; timestamp[0]=millis(); } if(millis()-timestamp[1]>=100 && flag_ir[1]){ counter[1]++; timestamp[1]=millis(); } if(millis()-timestamp[2]>=100 && flag_ir[2]){ counter[2]++; timestamp[2]=millis(); } // -- Disable --------------------------------------------- if(flag_match[0] && counter[0]>=115 && flag_ir[0]){ counter[0]=0; flag_ir[0]=0; flag_match[0]=0; msgCentral(1,0); // coffin IR0 } if(flag_match[1] && counter[1]>=74 && flag_ir[1]){ counter[1]=0; flag_ir[1]=0; flag_match[1]=0; msgCentral(2,0); // coffin IR1 } if(flag_match[2] && counter[2]>=44 && flag_ir[2]){ counter[2]=0; flag_ir[2]=0; flag_match[2]=0; msgCentral(3,0); // coffin IR2 } if(flag_match[3] && analogRead(A7)>=100){ flag_match[3]=0; msgCentral(4,0); // coffin IR3 } if(flag_match[0] && flag_match[1] && flag_match[2] && flag_match[3] && !flag_open){ flag_open=1; msgCentral(5,1); } // -- Receiver -------------------------------------------- if(radio.available()){ radio.read(&data,4); if(data[0]==3 && data[1]==2 && millis()-timestamp[5]>=150){ switch(data[2]){ // device code: 3 case 1: coffinOpen(); break; case 2: coffinClose(); break; } timestamp[5]=millis(); } } // -- Side light ------------------------------------------ if(analogRead(A5)>=180){ if(light_side_lev<255 && millis()-timestamp[6]>=15){ light_side_lev++; if(light_side_lev==255){ flag_secret=1; msgCentral(6,1); // secret open } timestamp[6]=millis(); } }else if(analogRead(A5)<180){ if(light_side_lev>0 && millis()-timestamp[6]>=7){ light_side_lev--; timestamp[6]=millis(); } } // -- Coals heating --------------------------------------- if(millis()-timestamp[7]>=300 && !digitalRead(7)){ timestamp[7]=millis(); if(coal_delta<5) coal_delta++; } if(millis()-timestamp[7]>=700){ coal_delta=0; } if(millis()-timestamp[8]>=100){ if(coal_level<250) coal_level+=coal_delta; if(coal_level>1) coal_level-=1; timestamp[8]=millis(); } if(coal_level>=250 && !flag_coals){ msgCentral(7,1); // coals heated, open flag_coals=1; } // -- side/coal output --------------------------------------- analogWrite(6,coal_level); if(light_side_lev<5) analogWrite(5,0); else analogWrite(5,light_side_lev); } void resetFlag(){ oldPosition=0; myEnc.write(0); posFlag=0; light_next=0; } void updateFlag(byte flag){ posFlag=flag; switch(posFlag){ case 1: light_next=4; break; case 2: light_next=12; break; case 3: light_next=39; break; case 4: light_next=86; break; case 5: case 6: light_next=255; break; } } void msgCentral(byte name,byte content){ data[0]=255; data[1]=1; data[2]=name; data[3]=content; radio.stopListening(); for(byte i=0;i<5;i++) radio.write(&data, 4); radio.startListening(); } void coffinOpen(){ // updateFlag(6); //DEBUG digitalWrite(1,0); digitalWrite(0,1); delay(500); digitalWrite(0,0); } void coffinClose(){ digitalWrite(1,1); delay(100); digitalWrite(0,1); delay(500); digitalWrite(0,0); digitalWrite(1,0); }
Комментарии скудны, так что задавайте вопросы. Времени в обрез, поэтому меня порадует любая помощь.
Вот что было выяснено:
1. При принудительном вызове updateFlag() в цикле, яркость повышается нормально, лента явно работает.
2. При поворотах энкодера она хаотично мигает, но иногда начинает разгораться до первой установки, как в случае updateFlag(1);
При некоторых условиях (они неизвестны, просто покрутили энкодер, в ту же сторону, или в другую сторону) лента перестаёт мигать вовсе.
3. Условие newPosition!=oldPosition не выполняется, с энкодера явно не приходит информация. Провода целы. Длина проводов 3 метра, три витых пары:
- питание (+5) и земля
- d2 и земля
- d3 и земля
Земли всех трёх пар соединены на плате энкодера (на стороне источника). Вроде всё по правилам. На плате собсно энкодер и подавитель дребезга на 7414. Осциллографа, чтобы посмотреть, что же там на самом деле, нет. Сериала нет. Если поставить в цикл вызов msgCentral(чтонибудь,(byte)newPosition) - приходят только нули, как если бы энкодер не крутился.
Вот что я думаю сделать, ибо дома, в тепличных условиях, плата энкодера (с короткими проводами да без лишнего в скетче) завелась с полпинка:
я поставлю ещё одну atmega8, она будет выдавать едницу нужной длины, чередующуюся коротким нулём, и по длительности единицы на основной плате понимать, куда откручен энкодер: три полных оборота вправо, два влево после этого и так далее. То есть, все чтения энкодера и функция updateFlag() переедут в отдельный контроллер.
Возможно, предложите ещё варианты.
возможно потому, что отсутсвует флаг
#define ENCODER_OPTIMIZE_INTERRUPTS
http://www.pjrc.com/teensy/td_libs_Encoder.html
и, вообще, кто запрещает использовать UART для отладки?
подключи по RX, TX атмега8 с HD44780 и пуляй в индикатор что тебе нужно
К сожалению не помогло. Новая проблема, плата внезапно поломалась: теперь с энкодера приходят только две цифры: 0 и 1, ни больше ни меньше. Замена энкодера ничего не даёт.
К сожалению не помогло. Новая проблема, плата внезапно поломалась: теперь с энкодера приходят только две цифры: 0 и 1, ни больше ни меньше. Замена энкодера ничего не даёт.
подозреваю, что железо у тебя во время публикации первого поста было сломано.
Окей all, всё что мне нужно, делается двумя ФД265 и компаратором LM393.
А энкодер послан нахер, бажное дилдо для цереброкоитальных утех. х█й его про███т как с ними работать.
ух ты какие значки... а как эти прямоугольники получились?
про энкодер -что мешает найти скетч с энкодером и попользовать необходимые куски?
Alt+219
Да видимо дело не в скетче. Непонятно, или энкодеры китайские рассыпались (неизвестно как, 4 шт подряд?) или схемы глушения дребезга какие-то левые (там вроде тоже ошибиться негде - RC цепочка 220R+1uF и триггер Шмитта). Так или иначе, проверить нечем.