#include <string.h>
#include <usb_serial.h>
-#define FIRMWARE_VERSION 0x011
+#define FIRMWARE_VERSION 0x012
//Channels 0 1 2 3: PD4, PB6, PF6, PF1
//Scc? -- read channel status - 2nd char: 'e' in case of overcurrent, 3rd char: enable 1/0
//Ccc? -- read current
//Dcc? -- read averaged current
+//Ecc? -- read raw ADC value
+//Bcc? -- read ADC channel offset
//Lccxxx -- set current limit (hex)
//Lcc? -- read current limit
//Axxx -- answer - three hex digits or chars
//Pcc(0|1) -- Do a automatic power cycle (2 seconds long)
//Rcc? -- read ADC measurement of internal 1.1V reference (one register)
//Icc? -- Firmware Info
+//F001 -- Force another calibration with relais
#define ISMYADDR() (rxbuf[1] == '0' && (rxbuf[2] == '0' || rxbuf[2] == '1' || rxbuf[2] == '2' || rxbuf[2] == '3') )
uint8_t output_error = 0;
uint8_t adc_enable = 1;
uint8_t calibphase = 1;
+uint8_t forcecalib = 0;
uint16_t adc_offset[4] = {0,0,0,0};
uint16_t adc[4];
+uint16_t raw[4];
uint16_t avgadc[4] = {0,0,0,0};
uint8_t countdown[4] = {0,0,0,0};
uint16_t adc_reference = 0;
if(to >= -1) {settings_changed |= 16;}
- if((output_enable & (1<< chan))) { // && !(output_error & (1<< chan))
+ if((output_enable & (1<< chan)) ) { // && !(output_error & (1<< chan))
switch (chan) {
case 0 : PORTD |= (1<<4); break;
case 1 : PORTB |= (1<<6); break;
}
if (adc[channel] > 0x300)
adc[channel] = 0;
- if(adc_offset[channel] > adc[channel] ) {
+ if(adc_offset[channel]+0x30 > adc[channel] ) {
adc[channel] = adc_offset[channel] - adc[channel];
adc[channel] *= 25;
}
else {
adc[channel] = 0;
}
+ if(channel == 3 && forcecalib == 1) {
+ calibphase = 1;
+ forcecalib = 0;
+ }
}
case 2:
case 3:
adc[channel] = ADC;
+ raw[channel] = adc[channel];
correct_adc(channel);
avgadc[channel] -= avgadc[channel]/8;
- avgadc[channel] += adc[channel];
+ if(adc[channel] < 0x800) {
+ avgadc[channel] += adc[channel];
+ }
if(limit[channel]*8<avgadc[channel]) {
output_error |= (1<<channel);
switchoutput(channel,-2);
}
void getdata(uint8_t buf) {
- if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C' || buf == 'I'
- || buf == 'D' || buf == 'O' || buf == 'P' || buf == 'R')) {
+ if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C' || buf == 'I' || buf == 'B' || buf == 'E'
+ || buf == 'D' || buf == 'O' || buf == 'P' || buf == 'R' || buf == 'F')) {
rxbuf[rxcnt++] = buf;
}
if (buf == '\n' || buf == '\r') {
//Read current command
if (rxbuf[0] == 'C' && rxbuf[3] == '?' && is_my_address(5)) {
- if(adc_enable == 3) { send_answer_hex(adc[rxbuf[2]]+0x800); }
- else { send_answer_hex(adc[rxbuf[2]]); }
+ send_answer_hex(adc[rxbuf[2]]);
}
//Read average current command
if (rxbuf[0] == 'D' && rxbuf[3] == '?' && is_my_address(5)) {
- if(adc_enable == 3) { send_answer_hex(avgadc[rxbuf[2]]/8+0x800); }
- else { send_answer_hex(adc_offset[rxbuf[2]]); } //avgadc[rxbuf[2]]/8
+ send_answer_hex(avgadc[rxbuf[2]]/8);
+ }
+
+//Read offset command
+ if (rxbuf[0] == 'B' && rxbuf[3] == '?' && is_my_address(5)) {
+ send_answer_hex(adc_offset[rxbuf[2]]); //avgadc[rxbuf[2]]/8
}
+//Read raw command
+ if (rxbuf[0] == 'E' && rxbuf[3] == '?' && is_my_address(5)) {
+ send_answer_hex(raw[rxbuf[2]]);
+ }
+
//Read firmware info
if (rxbuf[0] == 'I' && rxbuf[3] == '?' && is_my_address(5)) {
send_answer_hex(FIRMWARE_VERSION);
send_answer_hex(adc_reference);
}
}
-
+//Redo calibration without changing relais
+ if (rxbuf[0] == 'F' && rxbuf[3] == '1' && is_my_address(5)) {
+ forcecalib = 1;
+ }
+
//Set current limit
if (rxcnt == 7 && rxbuf[0] == 'L' && is_my_address(7)) {
limit[3] |= eeprom_read_byte((uint8_t*)0x26);
adc_enable = eeprom_read_byte((uint8_t*)0x28);
output_enable = eeprom_read_byte((uint8_t*)0x29);
- switchoutput(0,-3);
- switchoutput(1,-3);
- switchoutput(2,-3);
- switchoutput(3,-3);
-
+
//Timer0 at ~122 Hz overflow for ADC control and buttons
TCCR0B = (4 << CS00);
TIMSK0 = (1 << TOIE0); //Overflow interrupt`
UCSR1B = (1 << RXCIE1) | (0 << TXCIE1) | (0 << RXEN1) | (1 << TXEN1);
UCSR1C = (3 << UCSZ10); //8 Bit
UBRR1 = 0x10; //57600
- _delay_ms(10);
+ _delay_ms(100);
UCSR1B |= (1 << RXEN1);
ADMUX = (3 << REFS0); //reference 2.56V internal