==== Main.c (uses procyon avrlib) ==== #include "main.h" int get_char0(FILE* stream) { int c=-1; while(c==-1) {c=uartGetByte();} //getchar gets the stream, loop until we get something return (u08) c; } int put_char0(char c, FILE *stream) { loop_until_bit_is_set(UCSR0A, UDRE0); //unbuffered tx comms UDR0 = c; return 0; /* if(uartReadyTx || !uartBufferedTx ) //if buffer is empty or we arent buffered {uartSendByte(c); //sends directly to uart return 0; } else { //while(!bufferAddToEnd(Txbuff0,c)); //send the character to buffer if(uartAddToTxBuffer(c)) {return 0;} else {return -1;} }*/ } int pseudoscanf() { char s[20]; int d; fgets(s,20,stdin); sscanf(s,"%d",&d); return d; } float getHVvalue(int n) { if(n>0 && n<4) //sanity check { if (n==1) n=0; //corrects mistake on the board return hvfactor*((float)a2dConvert10bit(n)-520.0); //correct for unbalanced resistors on board } else { return -1; } } void overflow(void) { float delta=i_term*(p_setpoint-pressuredifference()); if(position>-delta) //ie we're not going to end up with -ive position position+=delta; if (position>1400.0) position=1400.0; //maximum limit on duty cycle timer1PWMASet((u16)position); } void temperatureprint() { int temp=a2dConvert10bit(temppin); printf("%d,%.1f\r\n",temp,-16.436*log(1.11258*((1024.0/(double)temp)-1.0))); //returns the thermistor temperature } float pressuredifference() { return (float)pressurefactor*((float)a2dConvert10bit(pressurepin)-pressurenull); } void set_control_loop(d) { if(d!=0) { if(!pump) timer1PWMAOn(); //if we set a target of zero, it turns off pwm completely, which is handy pump=TRUE; timerAttach(1,overflow); //ISR on pwm falling edge p_setpoint=(float)d/1000.0; } else { pump=FALSE; timerDetach(1); //ISR off pwm falling edge timer1PWMAOff(); } } void HVenable(int n) { if (n<4 && n>-1) { PORTD|=0b00011100; //turn it all off if (n) PORTD&=~(1<<(n+1)); //sending 0 will turn off all the HV supplies printf("HV %d enabled\r\n",n); } else printf("%d is not a HV channel\r\n",n); } void nullset(void) { u08 n; u32 s=0; for(n=0;n<255;n++) { s+=a2dConvert10bit(pressurepin); _delay_ms(7); } pressurenull=(float)s; pressurenull/=256; printf("%f = pressurenull\r\n",(double)pressurenull); } int main(void) { //int nodata=0; int d; signed char c; DDRD=0b00011100; //hv outputs PORTD=0b00011100; //set the outputs high ie all HV supplies off DDRB=0b00000010; //pump pwm PORTB=0x00; uartInit(); uartSetBaudRate(19200); FILE mystdio0 = FDEV_SETUP_STREAM(put_char0, get_char0, _FDEV_SETUP_RW); //so we can printf to the radio stdout = &mystdio0; //set our stdio out function stdin = &mystdio0; // sei(); //while(1) //{ //printf("hello\r\n"); //_delay_ms(20); //} timerInit(); timer1SetPrescaler(TIMER_CLK_DIV1); timer1PWMInitICR(4095); //timer1PWMAOn(); timer1PWMASet(0); a2dInit(); puts("setup ok\r\n"); nullset(); while(1) { c=uartGetByte(); //scanf("%c",&c);; //if(c!=-1) //{ //printf("%c\r\n",c); switch(c) { case 'V': //HV voltage feedback printf("%.0f\r\n",(double)getHVvalue(pseudoscanf())); //we only need it to the nearest volt break; case 'D': printf("%d,%.4f\r\n",a2dConvert10bit(pressurepin),(double)pressuredifference()); //Pressure feedback break; case 'H': d=pseudoscanf(); printf("got %d",d); HVenable(d); //turn on a HV supply break; case 'P': d=pseudoscanf(); //set a differential target - note in units of % of full range set_control_loop(d); break; case 'C': d=pseudoscanf(); i_term=(float)d/16.0; //set a correction factor (might need a dive term if things are messed with) break; case 'K': d=(int)(p_setpoint*1000.0); //store the setpoint set_control_loop(0); //turn off pump for(c=0;c<100;c++) _delay_ms(10); //wait 1 second nullset(); set_control_loop(d); break; case 'T': temperatureprint(); break; case 'I': printf("%.3f\r\n",ionfactor*((double)a2dConvert10bit(ionpin)-520.0)); //returns the ionisation current - opamp is using the split ie 2.5V rail break; //hence the 512 //default: //if (c!=-1) printf("command not found\r\n"); //nodata=0; } //} /*else { nodata++; for(d=0;d<50;d++) { _delay_ms(10);} //printf("%d,%f\r\n",nodata,(double)pressuredifference()); }*/ } return 0; }