дебажим гроб
- Войдите на сайт для отправки комментариев
Моей главной ошибкой, с переходом на 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_INTERRUPTShttp://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 и триггер Шмитта). Так или иначе, проверить нечем.