#include #include #include #include #include /* PENTAMETRIC SYSTEM COMMANDS*/ #define PM_READ 0x81 #define PM_BATTERY1_VOLTS 1 #define PM_BATTERY2_VOLTS 2 #define PM_AVERAGE_BATTERY1_VOLTS 3 #define PM_AVERAGE_BATTERY2_VOLTS 4 #define PM_AMPS1 5 #define PM_AMPS2 6 #define PM_AMPS3 7 #define PM_AVERAGE_AMPS1 8 #define PM_AVERAGE_AMPS2 9 #define PM_AVERAGE_AMPS3 10 #define PM_WATTS1 23 #define PM_WATTS2 24 #define PM_PERCENT_BATTERY1_FULL 26 #define PM_PERCENT_BATTERY2_FULL 27 #define PM_BATTERY1_VOLTS_bytes 2 #define PM_BATTERY2_VOLTS_bytes 2 #define PM_AVERAGE_BATTERY1_VOLTS_bytes 2 #define PM_AVERAGE_BATTERY2_VOLTS_bytes 2 #define PM_AMPS1_bytes 3 #define PM_AMPS2_bytes 3 #define PM_AMPS3_bytes 3 #define PM_AVERAGE_AMPS1_bytes 3 #define PM_AVERAGE_AMPS2_bytes 3 #define PM_AVERAGE_AMPS3_bytes 4 #define PM_WATTS1_bytes 3 #define PM_WATTS2_bytes 3 #define PM_PERCENT_BATTERY1_FULL_bytes 1 #define PM_PERCENT_BATTERY2_FULL_bytes 1 #define PANEL_VOLTAGE PM_BATTERY2_VOLTS #define PANEL_VOLTAGE_bytes PM_BATTERY2_VOLTS_bytes #define BATTERY_VOLTAGE PM_AVERAGE_BATTERY1_VOLTS #define BATTERY_VOLTAGE_bytes PM_AVERAGE_BATTERY1_VOLTS_bytes #define POWER_OUTPUT PM_AMPS2 #define POWER_OUTPUT_bytes PM_AMPS2_bytes short uart_error=0; //number of bytes in a received command #define MAX_CMD_SIZE 13 uint8_t cmd_buff[MAX_CMD_SIZE]; volatile uint8_t whole_cmd_received=0; volatile uint8_t cmd_pos=0; unsigned char last_cmd=0,last_cmd_bytes=3; uint8_t SEVENSEG[] = { 0b10001000, //0 0b11101011, //1 0b01001100, //2 0b01001001, //3 0b00101011, //4 0b00011001, //5 0b00011000, //6 0b11001011, //7 0b00001000, //8 0b00001011, //9 0b11111111 //BLANK }; #define BLANK 10 #define DECIMAL (1<<3) #define F_OSC 8000000 /* oscillator-frequency in Hz */ #define UART_BAUD_RATE 2400 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1) volatile long tmrms; SIGNAL (SIG_OVERFLOW0){ tmrms+=1; TCNT0=5; // Re-init timer } void inittimer(void){ TCCR0=0x03; // Prescaler CK/64---> @16MHz, counter is at 250kHz, so overflows at 1kHz = 1ms TCNT0=5; TIMSK=(1<>8); // UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC); UBRRL = 207; // Enable receiver and transmitter; enable RX interrupt UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); //asynchronous 8N1 UCSRC = (1 << URSEL) | (3 << UCSZ0) | (0<=3) curdig=0; t++; if (t==200) {t=0;u++;} now=gettmrms(); if ((now-last)>=200) { last=now; if (cmd_state==CMD_WAIT_RESPONSE){ yellow_decimal[2]=DECIMAL; //error flag: response not received if (cur_command==0) {blue_dig[0]=BLANK;blue_dig[1]=BLANK;blue_dig[2]=0;} if (cur_command==1) {led_bar=0b11111;} if (cur_command==2) {yellow_dig[0]=BLANK;yellow_dig[1]=BLANK;yellow_dig[2]=0;} cur_command++;if (cur_command>=3) cur_command=0; //try the next command }else yellow_decimal[2]=0; if (cur_command==0){ last_cmd=PANEL_VOLTAGE; last_cmd_bytes=PANEL_VOLTAGE_bytes; } if (cur_command==1){ last_cmd=BATTERY_VOLTAGE; last_cmd_bytes=BATTERY_VOLTAGE_bytes; } if (cur_command==2){ last_cmd=POWER_OUTPUT; last_cmd_bytes=POWER_OUTPUT_bytes; } cmd_state=CMD_SENDING_DATA1; /* //SEND REQUEST usart_putc(PM_READ); usart_putc(last_cmd); usart_putc(last_cmd_bytes); cksm = (0xFF - (PM_READ + last_cmd + last_cmd_bytes)); usart_putc(cksm); //checksum cmd_state=CMD_WAIT_RESPONSE; */ } // else { if ((UCSRA & (1 << UDRE))){ if (cmd_state==CMD_SENDING_DATA1){ UDR=(PM_READ); cmd_state=CMD_SENDING_DATA2; } else if (cmd_state==CMD_SENDING_DATA2){ UDR=(last_cmd); cmd_state=CMD_SENDING_DATA3; } else if (cmd_state==CMD_SENDING_DATA3){ UDR=(last_cmd_bytes); cmd_state=CMD_SENDING_DATA4; } else if (cmd_state==CMD_SENDING_DATA4){ cksm = (0xFF - (PM_READ + last_cmd + last_cmd_bytes)); UDR=(cksm); //checksum cmd_state=CMD_WAIT_RESPONSE; } } if (whole_cmd_received==1) { cli(); whole_cmd_received=0; cmd_pos=0; unsigned char checksum=0; for (i=0;i<(last_cmd_bytes+1);i++) checksum+=cmd_buff[i]; if (checksum==0xff){ /* MESSAGE RECEIVED! */ blue_decimal[2]=0; cmd_state=CMD_GOT_RESPONSE; if (cur_command==0){ //PANEL_VOLTAGE int volts=(cmd_buff[0]+(cmd_buff[1]<<8))/2; number_to_string(volts,blue_dig); blue_decimal[1]=DECIMAL; } if (cur_command==1){ //BATTERY VOLTAGE int volts=(cmd_buff[0]+(cmd_buff[1]<<8))/2; if (volts<240) led_bar=0b11110; //240 250 260 270 300 else if (volts<250) led_bar=0b11100; else if (volts<260) led_bar=0b11000; else if (volts<270) led_bar=0b10000; else if (volts<300) led_bar=0b00000; else {led_bar=0b00000;/*error condition: over voltage?*/} } if (cur_command==2){ //POWER OUTPUT //three bytes received: LSB MSB HSB //the first bit of LSB is the sign if (cmd_buff[2] & (1<<7)) //we're reading a negative value, so invert all bits {cmd_buff[0]=~cmd_buff[0];cmd_buff[1]=~cmd_buff[1];cmd_buff[2]=~cmd_buff[2];} unsigned long vv=0; vv=cmd_buff[2]; vv<<=8; vv|=cmd_buff[1]; vv<<=8; vv|=cmd_buff[0]; unsigned int watts=vv/4; //amps = vv/100.... watts=(vv/100) * 25V = vv/4 if (watts>999) watts=999; //don't update the display if we get a high reading number_to_string(watts,yellow_dig); } } else { /* CHECKSUM ERROR */ blue_decimal[2]=DECIMAL; cmd_state=CMD_CKSM_ERROR; } cur_command++;if (cur_command>=3) cur_command=0; sei(); } else _delay_ms(1); // } } return(0); }