Power budget broken by SIMS
Great use of the voltage sensor
Oled not so good in full sunlight still trouble with the water sensor
Water sensor broken
All onboard
I have some problem with the water level indication perhaps it needs recalibration. It is a resistor which has 176 Ohms when the tank is full and 0 when it is empty. I use a port on the CPU to feed a resistor in serie with the "water resistor" and then I measure the voltage in the middle acting as a voltage divider. The tank is calibrated by going from full to empty by emptying 10 liters a time and making a note of the output from the A/D converter.
Summer code
This is the code I will be running now for a while, perhaps I will find some bugs or see parts of the functionality I would like to change.
#include <msp430x20x3.h>
#include "bat.h"
void ad_3(void);
void send_char(unsigned char p_i);
void send_string_lcd(unsigned char row,unsigned char column, unsigned char *p_i);
void read_port(void);
void display_image(void);
void send_rectangle_lcd(unsigned char column, unsigned char row, unsigned char column_b, unsigned char row_b);
void show_voltage_2(void);
void show_item(unsigned char *p_k);
void show_2(unsigned char *p_2);
void show_amps(void);
void show_generator_2(void);
int seconds=0;
unsigned char buffer[6][9];
unsigned char size[]={7,7,7,7,8,2};
unsigned char colour_h,colour_l;
int vdo_counter=0;
int blink = 0;
int main( void )
{
asm(" mov.w #27Eh,SP");
P1OUT = 0x02; // Oled output high
P1DIR = 0xCF; // P1.1 Oled output P1.4 transistor base cutoff floating P.5 Zigbee input
BCSCTL3 |= LFXT1S_2; // VLO
P2SEL = 0; // do not use crystal oscillator
WDTCTL = WDT_ADLY_16; // WDT 16ms, ACLK, interval timer
// WDTCTL = WDT_ADLY_1000; // WDT 1000ms, ACLK, interval timer
IE1 |= WDTIE; // Enable WDT interrupt
for(;;){
_BIS_SR(GIE + CPUOFF + SCG1 + SCG0); // Enter LPM3 w/interrupt
}
}
// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
vdo_counter++;
if(vdo_counter == 1){
ad_3();
}
if(vdo_counter >= 18)
vdo_counter = 0;
}
void ad_3(void){
unsigned char k[4];
k[3] = 0;
seconds++;
if(seconds == 3 ){
send_char(0x55); // sync
}
if(seconds == 4 ){
display_image();
read_port();
show_amps();
k[0] = 'v';
k[1] = 'o';
k[2] = 'l';
show_item(&k[0]);
}
if(seconds == 5){
show_voltage_2();
}
if(seconds == 8){
k[0] = 's';
k[1] = 'o';
k[2] = 'l';
show_item(&k[0]);
}
if(seconds == 9){
show_2(&buffer[0][0]);
}
if(seconds == 11){
k[0] = 'g';
k[1] = 'e';
k[2] = 'n';
show_item(&k[0]);
}
if(seconds == 12){
show_generator_2();
}
if(seconds == 14){
k[0] = 'k';
k[1] = 'y';
k[2] = 'l';
show_item(&k[0]);
}
if(seconds == 15){
show_2(&buffer[2][0]);
}
if(seconds == 17){
k[0] = 'v';
k[1] = 'a';
k[2] = 'r';
show_item(&k[0]);
}
if(seconds == 18){
show_2(&buffer[3][0]);
}
if(seconds ==20){
send_char(0x59); // display off
send_char(0x01);
send_char(0x00);
}
if(seconds == 21 ){
P1OUT = 0x02; // P1.4 transistor cutoff Oled output high
P1DIR = 0xDF; // P1.1 Oled output P1.4 transistor base cutoff floating P.5 Zigbee inpu
}
if(seconds > 21){
if(blink == 0){
blink = 1;
P1OUT = 0x03;
}
else{
blink = 0;
P1OUT = 0x2;
}
}
}
void show_amps(void){
int i,t;
unsigned char k[5];
unsigned char v;
for( i = 0 ; i < 5 ; i++)
k[i] = 0;
// convert ascii to hex for generator,solarpanel,fridge and heater
for( i = 0; i < 4 ; i++){
t = 10;
v = buffer[i][6];
while ( v > 0x30 && t > 0){
k[i] = k[i] + 10;
v = v - 1;
t--;
}
t = 10;
v = buffer[i][7];
while ( v > 0x30 && t > 0){
k[i] = k[i] + 1;
v = v - 1;
t--;
}
}
// convert ascii to hex for water
if(buffer[5][0] == 0x31)
k[4] = k[4] + 100;
t = 10;
while ( buffer[5][1] > 0x30 && t > 0){
k[4] = k[4] + 10;
buffer[5][1] = buffer[5][1] - 1;
t--;
}
t = 10;
while ( buffer[5][2] > 0x30 && t > 0){
k[4] = k[4] + 1;
buffer[5][2] = buffer[5][2] - 1;
t--;
}
k[4] = k[4] >> 1;
colour_h = BLUE_HIGH;
colour_l = BLUE_LOW;
send_rectangle_lcd(0,0,k[4],4); // water
colour_h = BLACK_HIGH;
colour_l = BLACK_LOW;
send_rectangle_lcd(0,6,k[0],10); // generator
send_rectangle_lcd(k[0]+3,6,k[0] + k[1] + 3,10); // solar
colour_h = RED_HIGH;
colour_l = RED_LOW;
send_rectangle_lcd(0,12,k[2],16); // fridge
send_rectangle_lcd(k[2]+3,12,k[2] + 3 + k[3],16); // heater
}
void show_voltage_2(void){
unsigned char k[5];
unsigned char *p_buff;
k[3] = 0;
p_buff = &k[0];
send_rectangle_lcd(0,54,95,64); // black background
colour_h = WHITE_HIGH;
colour_l = WHITE_LOW;
k[4] = 0;
p_buff = &k[0];
k[0] = buffer[4][0];
k[1]=buffer[4][1];
k[2]='.';
k[3]=buffer[4][2];
send_string_lcd(7,0,p_buff);
k[0] = buffer[4][3];
k[1]=buffer[4][4];
k[2]='.';
k[3]=buffer[4][5];
send_string_lcd(7,5,p_buff);
k[0] = buffer[4][6];
k[1]=buffer[4][7];
k[2]='.';
k[3]=buffer[4][8];
send_string_lcd(7,10,p_buff);
}
void show_item(unsigned char *p_st){
colour_h = BLACK_HIGH;
colour_l = BLACK_LOW;
send_rectangle_lcd(0,54,95,64); // black background
colour_h = WHITE_HIGH;
colour_l = WHITE_LOW;
send_string_lcd(7,0,p_st);
colour_h = BLACK_HIGH; // prepere for next black background
colour_l = BLACK_LOW;
}
void show_generator_2(void){
unsigned char k[12];
unsigned char *p_buff;
p_buff = &k[0];
send_rectangle_lcd(0,54,95,64); // black background
k[0] = buffer[1][0];
k[1] = buffer[1][1];
k[2] = ' ';
k[3] = buffer[1][2];
k[4] = buffer[1][3];
k[5] = ' ';
k[6] = buffer[1][4];
k[7] = buffer[1][5];
k[8] = ' ';
k[9] = buffer[1][6];
k[10] = buffer[1][7];
k[11] = 0;
colour_h = WHITE_HIGH;
colour_l = WHITE_LOW;
send_string_lcd(7,0,p_buff);
}
void show_2(unsigned char *p_2){
unsigned char k[15];
unsigned char *p_buff;
p_buff = &k[0];
send_rectangle_lcd(0,54,95,64); // black background
k[0] = *p_2++;
k[1] = '.';
k[2] = *p_2++;
k[3] = ' ';
k[4] = *p_2++;
k[5] = '.';
k[6] = *p_2++;
k[7] = ' ';
k[8] = *p_2++;
k[9] = '.';
k[10] = *p_2++;
k[11] = ' ';
k[12] = *p_2++;
k[13] = *p_2++;
k[14] = 0;
colour_h = WHITE_HIGH;
colour_l = WHITE_LOW;
send_string_lcd(7,0,p_buff);
}
void display_image(void){
char low_b,mid_b,high_b;
low_b = 0;
mid_b = 0;
high_b = 0;
send_char(0x66);
send_char(high_b);
send_char(mid_b);
send_char(low_b);
}
void read_port(void){
int item;
unsigned char p = 0xFF;
long delay;
unsigned char a;
char b=0;
unsigned char d;
unsigned char search = 0x17;
int hit = 0;
BCSCTL1 |= RSEL3 | RSEL2 | RSEL1 | RSEL0; // increase speed
while(hit < 7 ){
d = 0;
p = 17; // not to trigger the while loop
while(p != 0){ // wait for startbit
p = P1IN;
p &= 0x20;
}
delay = 15;
while(delay > 1) // half bit extra delay at start
delay--;
for(a = 8; a > 0 ; a--){
delay = 33;
while(delay > 1)
delay--;
d = d >> 1;
P1OUT = 0x18; // set sample pin
p = P1IN;
p &= 0x20;
p = p << 2; // LSB first
d |= p;
} // one byte ready
if(search == 0x17 && d > 0x40 && d < 0x47){
search = 0x16;
item = d - 0x41;
}
else if(search == 0x16){
buffer[item][b++] = d;
if( b > size[item]){
search = 0x17;
b = 0;
hit++;
}
} // end of char
delay = 15;
while(delay > 1) // half bit extra delay at end
delay--;
} // end of timeout
BCSCTL1 = RSEL2 | RSEL1 | RSEL0; // reduce speed
}
void send_rectangle_lcd(unsigned char column, unsigned char row, unsigned char column_b, unsigned char row_b){
// 0x72,column,row,font_size,colour_high,colour_low,string,NULL
int d; // make sure previous command is ready
for( d = 0; d < 1000 ; d++);
send_char(0x72);
send_char(column);
send_char(row);
send_char(column_b);
send_char(row_b);
send_char(colour_h);
send_char(colour_l);
send_char(1);
}
void send_string_lcd(unsigned char row,unsigned char column,unsigned char *p_i){
// 0x73,column,row,font_size,colour_high,colour_low,string,NULL
int d; // make sure previous command is ready
for( d = 0; d < 1000 ; d++);
send_char(0x73);
send_char(column);
send_char(row);
send_char(0);
send_char(0xFF);
send_char(0xFF);
while(*p_i != 0)
send_char(*p_i++);
send_char(0);
}
void send_char(unsigned char p_i){
int p,i,j;
P1OUT = 0x1A;
BCSCTL1 |= RSEL3 | RSEL2 | RSEL1 | RSEL0; // increase speed
p = (int) p_i;
p = p << 1;
p |= 0x200; // add start and stop bit
for(i = 0; i < 10 ;i++){
for(j = 0; j < SERIAL_DELAY_384; j++);
if((p & 0x01) != 0)
P1OUT = 0x1A; // set bit high
else
P1OUT = 0x18; // set bit low
p = p >> 1;
}
P1OUT |= 0x02;
for(j = 0; j < SERIAL_DELAY_384; j++);
BCSCTL1 = RSEL2 | RSEL1 | RSEL0; // reduce speed
}