I've built a DIY telescope focuser using an ATTINY85 (overengineered, I know, but I wanted to be able to change the characteristics of the focuser without too much hassle). Long story short, I'm getting some weird bugs. Basically it works just fine, but every so often it will "freak out" and the servo will keep turning like crazy and the buttons will be unresponsive, like it's stuck in one of my loop statements. I'll attach my schematic, board and code.
int potVal = 0;//potentiometer value
int pwmVal = 0;//pwm mapped value
void setup() {
pinMode(0, OUTPUT); // PWM Output 1
pinMode(1, OUTPUT); // PWM Output 2
pinMode(2, INPUT); //Button 1
pinMode(3, INPUT); //Pot input
pinMode(4, INPUT); //Button 2
}
void loop() {
potVal = analogRead(3); //read potentiometer value
pwmVal = map(potVal, 0, 1020, 240, 36); //map pot value to pwm range
while (digitalRead(2) == HIGH) { //if button on input 2 is high, turn motor at pwmVal
potVal = analogRead(3); //read potentiometer value
pwmVal = map(potVal, 0, 1020, 240, 36); //map pot value to pwm range
analogWrite(0, pwmVal);
digitalWrite(1, LOW);
}
while (digitalRead(4) == HIGH){ //if button on input 4 is high, turn motor at pwmVal
potVal = analogRead(3); //read potentiometer value
pwmVal = map(potVal, 0, 1020, 240, 36); //map pot value to pwm range
digitalWrite (0, LOW);
analogWrite (1, pwmVal);
}
digitalWrite (0, LOW);
digitalWrite (1, LOW);
}
Any help would be appreciated!
EDIT: edited the comments in the code to reflect correct input numbers
Yea, that read and map is an artifact from trying to debug, I didn't think it would hurt to leave it there. Do you think that could be the problem? I don't know about built in pull-ups on the ATTINY85, I'm using 10k pull-downs for the two buttons.
Sorry about my schematic, I realize it's not too clear. Basically it's just a 5v regulator, 2 10uf smoothing caps for the power supply, an ATTINY85, an H-Bridge IC and a pot to control PWM value.
THe problem is, when I try to use the focuser like I normally would, everything works fine (pot controls speed, buttons control direction) but if one button is pressed too many times too quickly, it will just freak out and it will get stuck in a loop i.e. keep spinning. Additionally, when measuring with a voltmeter I noticed that when the focuser does "freak out", it outputs the maximum PWM value to the motor, regardless of the potentiometer setting. It keeps spinning till the focuser is turned off.
AnalogWrite takes a value from 0-255. AnalogRead of your pot can give a value between 0 and 1023. I'm not sure what will happen if you exceed the limit on the write, but it doesn't seem like a good idea. Try using a mapped value or just divide the AnalogRead reading by four. Also, why not AnalogWrite(pin,0), rather than digitalWrite(pin,0)?
Take a look at my code again, I'm not sure I'm exceeding the limit for analogWrite, in fact I deliberately mapped it so that I had a good buffer between the low and high range of limits, i.e. 0-1023 gets mapped to 240-30 (I mapped it backwards to reverse the direction you need to turn the pot to increase or decrease the value).
Personally I feel the error is in the board, but I can't figure it out, I'm a novice at EagleCAD. The code looks fine to me, unless anyone can find any mistakes there...
I suggest you disable the write statements that move the focus motors and put some debug print statements in the code handling button presses. I don't see anything wrong with the code (except the redundant code referred to above) but by testing it you can confirm that it does what you expect and correctly detects short button presses, frequent button presses, long button presses and so on. Then reinstate the write statements but leave the output pins physically disconnected. Does it still detect the inputs correctly? It should work just the same, unless there is something strange going on. Then connect up the output circuits. Does it still detect button presses correctly?
Although your code will work OK, as far as I can see, using the while() loop approach, I'd prefer a design where each call to loop() polls the two inputs looking for button up/down events and then starts/stops the corresponding motor when a button change occurs. I don't think this will solve your problem, but to me it seems a cleaner design that would allow your sketch to do things concurrently instead of hanging while a button is pressed.
I have on hand: a handful more ATTINY85s, caps, resistors and pots a-plenty. Quick question, the pot I'm using, I just measured to be a 16k linear pot, could it be too high a value?
I should mention, I have an UNO as well (which I used as an ICSP for the ATTINY85), no FTDI board or anything so any and all serial debugging will have to take place on an atmega328, is that a problem?