I have a DC motor turning a disc at around 5 rpm. I use a hall effect gear tooth sensor to monitor its position. Periodically, based on the sensor input, my ATMega2561 stops the motor (both by killing its power through a transistor and shorting its leads through another transistor). The cpu's supposed to pause for a second, start the motor up again, and wait for another sensor hit.
If I comment out the pause, the motor runs continuously (well, it stops with each sensor hit but immediately starts again). The input from the sensor (active low) appears as it should on a scope. If I enable the pause, the sensor input becomes erratic and the motor turns spastically as a result. I can't figure out why the pause would have any impact on the sensor. Even though the input pin I'm using (PINB6) is an output compare and PWM pin for timer 1 (which I use to generate the pause), I'm not using either of those modes. Also, I get the same erratic behavior if I use a couple of nested loops to generate the delay instead of the timer. Any thoughts what might be causing this behavior? Thanks.
//ICC-AVR application builder : 6/17/2009 9:52:10 PM // Target : m2561 // Crystal: 16.000Mhz #include#include void port_init(void) { PORTB = 0x00; DDRB = 0xA0; } //TIMER1 initialize - prescale:1024 // WGM: 0) Normal, TOP=0xFFFF // desired value: 1Hz // actual value: 1.000Hz (0.0%) void timer1_init(void) { TCCR1B = 0x00; //stop TIFR1 |= 1; // Reset OVF TCNT1H = 0xC2; //setup TCNT1L = 0xF7; TCCR1A = 0x00; TCCR1C = 0x00; TCCR1B = 0x05; //start Timer } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts XMCRA = 0x00; //external memory XMCRB = 0x00; //external memory port_init(); MCUCR = 0x00; EICRA = 0x00; //pin change int edge 0:3 EICRB = 0x00; //pin change int edge 4:7 PCICR = 0x00; //pin change int enable PCMSK0 = 0x00; //pin change mask EIMSK = 0x00; TIMSK1 = 0x01; //timer1 interrupt sources PRR0 = 0x00; PRR1 = 0x00; //all peripherals are now initialized } // void main(void) { init_devices(); PORTB = 0x80; // Turn on motor (active high on B7) while ((PINB & 0x40) == 0); // Wait for sensor to clear (active low on B6) while (1) { while ((PINB & 0x40) == 0x40); // Wait for sensor hit (active low on B6) PORTB &= ~0x80; // Turn off motor PORTB |= 0x20; // Turn on brake (active high on B5) timer1_init(); // Wait a second while ((TIFR1 & 1) == 0); PORTB &= ~0x20; // Turn off brake PORTB |= 0x80; // Turn on motor while ((PINB & 0x40) == 0); // Wait for sensor to clear } }