Power budget broken by SIMS

My daugther has started to play SIMS 2 or is it 3. The current clamp is showing 7.8 amps and the voltage is down to 11.8. I probably have to connect to the 220 volts supply tomorow.

Great use of the voltage sensor

We have now been out sailing for a week without plugging in to external power. This saves us 50 swedis crowns a day (approx the price of a good beer in a bar). The minimum voltage use to be around 12.7 volts wich makes me feel safe for the moment. There is a risk for my daugther using her PC more in the next week which migth make me plug the boat into the 220 volts.

Oled not so good in full sunlight still trouble with the water sensor

The Oled turned out to be almost unreadable in full sunlight, but since it's only 0.9 inch it is not a big area that needs to be covered. I changed the A/D input to the port next to the one i used. This port is able to go down below the maximum value but when I connect the resistive sensor to the A/D the reading is still not whar I expected.

Water sensor broken

Somehow the A/D for the water sensor seems to be broken, even if I set the input to 0 volts the measurement outputs 0x3FF, I will make a try to change the int and resolder the wire.

All onboard

I have now installed all the sensors. I was a little puzzled by the solar panel which indicated that it had produced 0 amphours last 24 hours. But the voltage on the batteries is 14.0 volt so I guess it is a sign for fully charged batteries.
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

}


Emulation of sensors

Since half of the sensors are mounted in the boat I need something to emulate them. I put toghether a CPU and Zigbee module to send normal strings for all the 6 sensors. I was a bit afraid that the reception would not be fast enough but it turned out not to be a problem.

I managed the 9 mm height

After some fiddling with the cables connecting the different parts all the hardware is now inside the box. I made some connectors for the batteries in case they will run flat. In theory it will happen after I made some 250 mesurements. This ends up to 7 measurements a day on a 5 week period which should be more than necessary. I measured the leakage current to 0.00 mA but the analog part has only been tested for some hours. 

Hardware crammed into Ipod box


Change of power on/off

I made some change to the power on/off. Now the CPU does not actively feed the base input with a current but it turns it off. I was worried about some debouncing at power off but I think it looks very good on the oscilloscope.

Power off


Sister board problems

When mounting the sister board I put the required 10 uF capacitor on the 3.3 volts. This caused big problems, the CPU turns off the relay by a port connected to the base of a BC547. When turned off the capacitor slowly reduces the voltage. It seems like at some point the Zigbee unit is releasing it's load and the voltage rices enough for the CPU to restart and enable the driving of the relay. To avoid this I have settled for a real retro style with an enormous switch, the CPU will use the onboard LED to blink in the end making it a multimedia show and also force you to turn the thing off. The original board is working ok without the capacitor, but I am thinking about a one shot solution instead of CPU contolled turn off.

Retro construction


RSS 2.0