Title: Problems with input on attiny85 using codevision avr
Post by: bytraper on June 02, 2023, 02:29:17 14:29
Hey guys. I am having some issues with my inputs on my attiny85. The inputs for the hardware are working fine, but it seems I've either changed something or done something wrong somewhere, to the point its not reading the ADC inputs at all. I have included the schematic so you can see what I'm trying to do. The code is as follows and is made with codevision. The schematic is attached. #include <tiny85.h> #include <eeprom.h> #include <delay.h>
void motordrive(void); void readeeprom(void); void callibration(void); void getinputs(void); unsigned char bcount = 15;
// Voltage Reference: AVCC pin #define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<REFS2) | (0<<ADLAR))
// Read the AD conversion result unsigned int read_adc(unsigned char adc_input) { ADMUX=(adc_input & 0x0f) | ADC_VREF_TYPE; // Delay needed for the stabilization of the ADC input voltage delay_us(10); // Start the AD conversion ADCSRA|=(1<<ADSC); // Wait for the AD conversion to complete while ((ADCSRA & (1<<ADIF))==0); ADCSRA|=(1<<ADIF); return ADCW; }
long int command; int current, pa, pb; long int burn; unsigned char go, roll = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, mode = 0, model, but0 = 0, but1 = 0, but2 = 0, but3 = 0, but4 = 0, but5 = 0, but6 = 0, but7 = 0, bcount2 = 0, sstart, sstop, cod = 0; // 0-255 int count, highc, lowc; // high and Low limit of current chosen by user dependant on controller direction. Also containd Maximum current for both directions. int low, high; //-32768 to 32768 the highest voltage from the input device char dir, ss, modelcount = 3; // this is the amount of ccurrently active models (not including 0) we have 1, 2 and 3. unsigned int inputvalue = 0,but0c = 0 ,but1c = 0, but2c = 0, but3c = 0, but4c = 0, but5c = 0, but6c = 0, but7c = 0;
void main(void) { PORTB = 0x00; DDRB = (1 << DDB1) | (1 << DDB0); // sets PB1 and PB0 as output, the rest are inputs by default delay_ms(100); CLKPR = 0x80; CLKPR = 0x00; TCCR0A = 0xA1; //0xA1; TCCR0B = 0x01; //Changing this to 01 gives us 18khz OK!!! 02 gives us 2.5khz 03 gives us 250hz!!!! OCR0A = 0x00; OCR0B = 0x00; GIMSK = 0x00; MCUCR = 0x00; ACSR = 0x83; //was 0x80 ADCSRB = 0x00; DIDR0 = 0x00;
ADCSRA = (1 << ADEN) | (0 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
readeeprom(); cod = 0; go = 0;
while (1) { go=0;
command = read_adc(3); delay_ms(10); //0-1024 This reads the input on the potentiometer input then adds a delay for the read.. Read the button states but1, 2, 3, 4, 5, 6, 7... anything past button 3 is hard to press at the same time
getinputs();
// ALL THE MODEL DATA IS HERE. Currently there are models 1,2,3. i may add other models to this as time goes on. if (model == 1) { go = 0; if (but1 == 1) {go = 1; dir = 0;} if (but2 == 1) {go = 1; dir = 1;} if ((but3 == 1) || (but0 == 1)) {go = 0; but2c = 0; but1c = 0; but3c = 0;}}
if (model == 2) { go = 1; if ((but1 == 1) || (but2 == 1) || (but3 == 1)) {if (dir == 1) {cod = 1; dir = 0;}} else {if (dir == 0) {dir = 1; cod = 1;}} }
if (model ==3) { go=1;cod=1; if (command>high) command=high; // low = 0 to 1024 1016 || low 10 || 181 || 45.25 if (command<low) command=low; // high 0 to 1024 55 || high 1011 || 800 || 200 burn = (command-low); burn = burn * 1024; // = 925 * 1024 = 947200 || 407 * 1024 = 416768 || -149 * 1024 burn = burn / (high-low); // = 947200 / 961 = 985.63995 || 416768 / 1001 = 416.35 || -152576 / 1001 command = burn; command = command -512; // = 985 - 512 = 473 || 416-512 = -95.64 || -152.42 command = command /2 ; // = 473 / 2 = 236.8 || 95.64 / 2 = 47.82 || }
else { if (command >= high) command = high; if (command <= low) command = low; burn = ((command - low) * 255); burn = (burn / (high - low)); }
if (go == 0) { OCR0A = 0x00; // shut down both outputs! OCR0B = 0x00; } else motordrive(); } }
//================================================================================================================= void motordrive(void) { if (model != 3) { if (dir == 0) {command = burn;} else {command = -burn;} } else { if (command > 0) {pa = command; pb = 0x00;} else {pa = 0x00; pb = -command;} // Reverse mode if (pa >= 255) pa = 254; if (pb >= 255) pb = 254; if (pa < 10) {pa = 0;} if (pb < 10) {pb = 0; } }
OCR0A = (char) pa; OCR0B = (char) pb; // MCU Pin 5 and 6 } //---------------------------------------------------------- newer sooft start routine -----------------------------------------------------------------------
//==============================================Gets the inputs from the multiplexed inputs=================================================================== void getinputs(void) {
if (mode == 0) //mode should always = 0 unless there's a function call already in progress { current = read_adc(0); delay_ms(5); // This is the input for the second trimpot. If its less than 2 then its turned all the way anti-clockwise. if (current < 2) {bcount2 = 1;} //This means the user wants to setup the controller, so the buttons will have NO visible actions. else {bcount2 = 0;} }
inputvalue = read_adc(2); delay_ms(5); // adc2 is the input from the multiplexed pin with delay for adc to settle.
if (inputvalue <= 70) {but0c++;} if (but0c>=bcount) {but0c=bcount;but0=1;} if ((inputvalue >= 85) && (inputvalue <= 110)) {but1c++;} if (but1c>=bcount) {if (bcount2 == 1) {but1 = 0; x4 = 1; roll = 1;}} else {but1 = 1;but1c=bcount;} if ((inputvalue >= 160) && (inputvalue <= 185)){but2c++;} if (but2c>=bcount) {if (bcount2 == 1) {but2 = 0; x4 = 2; roll = 1;}} else {but2 = 1;but2c=bcount;} if ((inputvalue >= 280) && (inputvalue <= 305)){but3c++;} if (but3c>=bcount) {if (bcount2 == 1) {but3 = 0; x4 = 4; roll = 1;}} else {but3 = 1;but3c=bcount;} if ((inputvalue >= 330) && (inputvalue <= 355)){but4c++;} if (but4c>=bcount) {but4c=bcount; but4 = 1;} if ((inputvalue >= 225) && (inputvalue <= 247)){but5c++;} if (but5c>=bcount) {but5c=bcount; but5 = 1;} if ((inputvalue >= 370) && (inputvalue <= 400)){but6c++;} if (but6c>=bcount) {but6c=bcount; but6 = 1;} if ((inputvalue >= 410) && (inputvalue <= 440)){but7c++;} if (but7c>=bcount) {but7c=bcount; but7 = 1;} if (roll == 1) {x4 = x3; x3 = x2; x2 = x1; roll = 0;}
if ((x1==1) && (x2==1) && (x3==2) && (x4== 1)) {mode = 1;} // 1121 if ((x1==4) && (x2==2) && (x3==2) && (x4== 4)) {mode = 2;} // 4224 if ((x1==2) && (x2==4) && (x3==2) && (x4== 1)) {mode = 3;} // 2421 if ((x1==1) && (x2==4) && (x3==1) && (x4== 4)) {mode = 4;} // 1414 if ((x1==4) && (x2==1) && (x3==2) && (x4== 4)) {mode = 5;} // 4124 if ((x1==4) && (x2==4) && (x3==1) && (x4== 3)) {mode = 6;} // 4412 if ((x1==2) && (x2==4) && (x3==1) && (x4== 4)) {mode = 7;} // 2414 if ((x1==1) && (x2==1) && (x3==2) && (x4== 2)) {mode = 8;} // 1122 if ((x1==4) && (x2==1) && (x3==4) && (x4== 2)) {mode = 9;} // 4142 if ((x1==2) && (x2==4) && (x3==1) && (x4== 2)) {mode = 10;} // 2412
if (mode > 0) { if (mode == 1) {mode = 0;} //{setsoftfast2();} (buttons 3-1-3-2 while trimpot on board is set to the 0 position) Allows you to setup the the soft stop speed or turn it off completely. ********* TAKEN ********** if (mode == 2) {callibration();} //(2113) Allows you to setup your input device, once this is activated you have a few seconds to move your input device back and forth. ********* TAKEN ********** if (mode == 3) {mode = 0;} //(1233) if (mode == 4) {mode = 0;} //{currentsetup1();} //(2323) // setup the current in the fwd direction ********* TAKEN ********** if (mode == 5) {mode = 0;} //{currentsetup2();} //(3132) // setup the current in the fwd direction ********* TAKEN ********** if (mode == 6) {mode = 0;} // (3331) mode0 means it returns if (mode == 7) {mode = 0;} //{setsoftfast1();} 3332 // Allows you to setup the the soft stop speed or turn it off completely. ********* TAKEN ********** if (mode == 8) {model = 1; mode = 0;} // turn the model into a model 1 ********* TAKEN ********** if (mode == 9) {model = 2; mode = 0;} // turn the model into a model 2 ********* TAKEN ********** if (mode == 10) {model = 3; mode = 0;} // turn the model into a model 3 ********* TAKEN ********** }
if (but0==1) {but0=0;but0c=0, but1c=0; but2c=0; but3c=0; but4c=0; but5c=0; but6c=0; but7c=0; but0=0; but1=0; but2=0; but3=0; but4=0; but5=0; but6=0; but7=0;go=0;}
}
//================================================================================================================= void readeeprom(void) { model = eeprom_read_byte(0); delay_ms(10); if ((model == 0) || (model > modelcount)) // if the model is within range then we probably have a programmed unit ready to go, so read the data and away we go (this may change between revisions)! { model = 3; high = 1023; low = 0; ss = 1; dir = 0; sstart = 1; sstop = 1; highc = 50; lowc = -50; eeprom_write_byte(0, model); delay_ms(2); eeprom_write_word(1, high); delay_ms(2); eeprom_write_word(3, low); delay_ms(2); eeprom_write_byte(5, ss); delay_ms(2); eeprom_write_byte(6, dir); delay_ms(2); eeprom_write_byte(7, sstart); delay_ms(2); eeprom_write_byte(8, sstop); delay_ms(2); eeprom_write_word(9, highc); delay_ms(2); eeprom_write_word(11, lowc); delay_ms(2); } else { model = eeprom_read_byte(0); delay_ms(2); high = eeprom_read_word(1); delay_ms(2); low = eeprom_read_word(3); delay_ms(2); ss = eeprom_read_byte(5); delay_ms(2); dir = eeprom_read_byte(6); delay_ms(2); sstart = eeprom_read_byte(7); delay_ms(2); sstop = eeprom_read_byte(8); delay_ms(2); highc = eeprom_read_word(9); delay_ms(2); lowc = eeprom_read_word(11); delay_ms(2); } }
//================================================================================================================= void callibration(void) { low = 1023; high = 0;
for (count = 0; count <= 4500; count++) { command = read_adc(3); delay_ms(10); if (command <= low)low = command; if (command >= high)high = command; } eeprom_write_word (1, high); delay_ms(30); eeprom_write_word (3, low); delay_ms(30); mode=0; }
Title: Re: Problems with input on attiny85 using codevision avr
Post by: dennis78 on June 04, 2023, 12:11:44 12:11
Hi,
1. If you show code and sch why you can't simple attach all project files? I ask this because it easy to try and look... 2. How you know you adc readings are wrong? Depend of values or program behavior?
On first look this simple program looks little confuse but ok if know what is it.
Several things (i think it will be better):
command = read_adc(3); delay_ms(10); -> command = (long int)read_adc(3); delay_ms(10); if (command>high) command=high; -> if (command>high) command=(long int)high; if (command <= low) command = low; -> if (command <= low) command = (long int)low;
All cases butXc>=bcount) {butXc=bcount -> butXc>=(unsigned int)bcount) {butXc=(unsigned int)bcount
strange line: if (command > 0) {pa = command; pb = 0x00;} else {pa = 0x00; pb = -command;} -> if (command > 0) {pa = (int)command; pb = 0x00;} else {pa = 0x00; pb = -command;? pb-=(int)command or?}
current = read_adc(0); delay_ms(5); if (current < 2) {bcount2 = 1;} -> i don't know what you try but this is very bad bad practice to compare with very low value. Adc=2 is value around noise floor of this adc (maybe ok for proteus simulation but not for real world)
Maybe you have more than this problematic cases but first try this.
Best regards
|