tv out arduino code stops?
I recently wrote some code for an arduinio to read an encoder and display it via RCA.
Problem is, it sometimes freezes on a blank screen when I'm turning the encoder.
Any ideas why? the code is below. And yes, I know that the interrupts mess with the signal and it flickers, I want to know why it will stay off whenever the encoder is halfway through a cycle.
#include <TVout.h>
float anaval = 0;
float value01 = 0;
int val = 1;
float value;
float value10;
float value100;
int out;
int r = 0;
float pos = 0;
int rd = 4;
float incr = 0.00078125;
TVout TV;
unsigned char x,y;
char i = 48;
void setup() {
pinMode(2, INPUT);
pinMode(7, INPUT);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);
attachInterrupt(0, encoderPos, CHANGE);
x=0;
y=0;
TV.begin(_NTSC,128,56); //for devices with only 1k sram(m168) use TV.begin(_NTSC,128,56)
}
void loop() {
disp();
// TV.clear_screen();
// TV.print_char(4,4,char(value100)+48);
// TV.print_char(10,4,char(value10)+48);
// TV.print_char(16,4,char(value)+48);
// TV.print_char(22,4,char(value01)+48);
}
void stringer(){
value01 = val;
value = val / 10;
value10 = val / 100;
value100 = val / 1000;
value = int(value);//rounds the variables
value10 = int(value10);
value100 = int(value100);
value01 = int(value01);
value01 = value01 - (value * 10);//removes all but the tenths-place digit
value = value - (value10 * 10);
value10 = value10 - (value100 * 10);
}
void encoderPos(void){ //this is a state machine to determine the direction of the encoder.
//every half-cycle it counts, effectively doubling the encoder resolution.
r = 1;
disp();
if(digitalRead(2) == HIGH){
if(digitalRead(7) == LOW){
while(r == 1){
disp();
if(digitalRead(2) == LOW){
r = 0;
} else {
if(digitalRead(7) == HIGH){
pos = pos + incr;
r = 0;
}}}
}
else {
while(r == 1){
disp();
if(digitalRead(2) == LOW){
r = 0;
} else {
if(digitalRead(7) == LOW){
pos = pos - incr;
r = 0;
}}}
}
}else{//same as the above code, but with High-Low reversed.
r = 1;
if(digitalRead(7) == HIGH){
while(r == 1){
disp();
if(digitalRead(2) == HIGH){
r = 0;
} else {
if(digitalRead(7) == LOW){
pos = pos + incr;
r = 0;
}}}
}
else {
while(r == 1){
disp();
if(digitalRead(2) == HIGH){
r = 0;
} else {
if(digitalRead(7) == HIGH){
pos = pos - incr;
r = 0;
}}}
}
}
}
void disp(){
val = int(pos * 1000);
TV.print_char(4,4,char(value100)+48);
TV.print_char(10,4,char(value10)+48);
TV.print_char(16,4,char(value)+48);
TV.print_char(22,4,char(value01)+48);
// TV.delay_frame(1);
stringer();
}
Comments
7 years ago
You should NEVER put while loops in interrupt routines - the interrupts is holding the whole processor to ransom as it waits.
Answer 7 years ago
Unfortunately, I couldn't find any other way to do it. Do you know where I can find the code for an encoder (the one on this site is incredibly glitchy), that doesn't use while statements? Or is there a way to make a sort of interrupt-statement (when x do y, but in the mean time, run the rest of the loop). I'm using an UNO, so I only have two interrupt pins, but I do need the other for the other half of this project, which I cannot work around (at least, not any way I can see).
Answer 7 years ago
Look at edge-triggered interrupts here. Time polling is not the way to go. Even simpler is to use a flip-flop to do direction sensing.
Answer 7 years ago
Depending on the exact microcontroller used it the arduino, you can probably set up the pin change interrupts on a couple of the spare pins to pick up the encoder signals. This should work the same as the dedicated interrupts, but just requires a few more lines of code to check which pin changed