I have my servos programmed and working well, even without PWM. (I built admin's board). I can set the servos to any speed with my code. Now I'm trying to get the light sensors to work. I wrote my program so that the servo opposite the photoresistor allowing a higher voltage would turn at full speed and the other would remain still. However, the servos stop and go seemingly randomly when I run the code, even if I cover one photoresistor and shine a light on the other. I'm using the medium-sized photoresistors from radioshack. They have around 1kOhm when shined with light and about 400kOhm when in a dark space. I am using a 100kOhm resistor. The photoresistors are mounted under the chassis. My MCU is the atmega328p at 1MHz. I have searched the forum and troubleshooted my bot for several hours with no change. I have tested all of the connections several times. None of the pins are shorted. I'm using pins 0 and 5. I also tried to get admin's photovore project to work, just changing the pin numbers, with no luck. With my program, the most I've accomplished is observing a small change in the servo behavior if I repeatedly cover and uncover one of the photosensors, but this only produces jerking to the same rhythm as my presses. One oddity I noticed was that there is only 8kOhm between power and ground pins for PORTC. Is this a wiring flaw, or due to the connection at the voltage regulator? I can't figure this out. My code is below. Thanks.
//Photovore
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
//This is used to count milliseconds by 2
volatile unsigned int clock_2millisecond=0;
volatile unsigned int servo_2millisecond=0;
volatile unsigned int sensor_2millisecond=0;
volatile unsigned int clock_second=0;
uint16_t leftEye=0;
uint16_t rightEye=0;
volatile int leftSpeed = 0;
volatile int rightSpeed = 0;
void DelayLoops(uint16_t nloops){
while(nloops>0){
nloops--;
}
}
void InitADC() {
ADMUX=(1<<REFS0); // Aref=AVcc
ADCSRA=(1<<ADEN)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Enable ADC, w/ Prescalar=8
}
uint16_t ReadADC(uint8_t ch){
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single Conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing a 1 to it.
//This seems odd, but the end result is a zero in the bit
ADCSRA|=(1<<ADIF);
//Return Result
return(ADC);
}
int main() {
//Set PinD as Output
DDRD = 0xFF;
PORTC= 0x00;
InitADC();
//Set up the timer1
//Set Prescaler to 8 and mode to CTC
TCCR1B=(1<<WGM12)|(1<<CS10);
//The below compare value for 2ms was found empirically for 1MHz with the debugger
//and will differ with other frequencies.
OCR1A=1999;
//Enable the Output Compare A interrupt
TIMSK1|=(1<<OCIE1A);
//Enable interrupts globally
sei();
//infinite loop comparing L&R sensors
while(1){
if(clock_2millisecond>200){
rightEye= ReadADC(0);
leftEye= ReadADC(5);
}
if(rightEye>leftEye){
leftSpeed = 0;
rightSpeed= 20;
}
if(leftEye>rightEye){
leftSpeed = 20;
rightSpeed= 0;
}
}
return 0;
}
//ISR called every 2ms
ISR(TIMER1_COMPA_vect) {
clock_2millisecond++;
servo_2millisecond++;
if(servo_2millisecond==10)
{
servo_2millisecond=0;
//Send Servo Signals
//Right Servo (PORTD Pin 1)
PORTD|=0b00000010;
DelayLoops(81+rightSpeed);
PORTD=0x00;
//Left Servo (PORTD Pin 0)
PORTD|=0b00000001;
DelayLoops(81-leftSpeed);
PORTD=0b00010000;
}
if(clock_2millisecond>=500){
clock_second++;
clock_2millisecond=0;
}
}