Strömmätare

Berätta om dina pågående projekt.
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Strömmätare

Inlägg av simon78 »

Jag har byggt en strömmätare, eller vad man ska kalla det. Det är en apparat som visar momentan ström (A), samt Ah, integrerat över tid. Den har två "kanaler" med en gemensam ledare, eller typ änna liksom... se bilden så blir det kanske förståligt
Bild

Tanken är att jag ska ha den i båten. Den gemensamma ledaren kopplas till batteriet, och ledarna märkta 1 och 2 kopplas till varsin plusskena. Då kan man mäta förbrukningen på olika förbrukare (kylskåp, belysning etc) och laddare (generator, solpanel, etc). Det är tänkt att man lätt ska kunna koppla om en förbrukare/laddare mellan de olika skenorna medelst strömbrytare, så om man tex vill se skillnaden mellan vad solpanelen ger och vad kylskåpet drar så lägger man över dem på samma skena. Vill man istället se dem individuellt lägger man dem ensamma på en skena.

Displayen visar som sagt A och Ah för varje kanal. Det finns två resetknappar för att nollställa respektive kanal.

Processor: atmega88
strömsensorer: ACS0752-SCA050 halleffektssensorer.
Displayen är en helt vanlig sodjan-display :)

Jag känner mig riktigt nöjd just nu. Får hoppas att den funkar lika bra IRL som på testbänken.

Då äre bara plusgrader som saknas för att man ska börja med båten... det brukar det ju vara gott om vid den här tiden men...
Senast redigerad av simon78 8 januari 2008, 21:00:52, redigerad totalt 1 gång.
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Praktiskt projekt! :) :tumupp:

Sådana skulle man ha i varje rum i lägenheten..


"sodjan-display", jo det är ett känt märke här på forumet. :)
symlah
Inlägg: 7
Blev medlem: 24 mars 2006, 12:37:56

Inlägg av symlah »

Riktigt intressant projekt inför båtsäsongen. Har länge funderat på att göra något liknande för kommersiella kostar ju runt 2000-3000 kr. Har du lust att beskriva lite mer vad du gjort? Det jag undrar över är vad noggranheten är, och då framför allt när man laddar batteriet under motorgång.

Var har du hittat kretsarna. ELFA har inte Allegros sortiment.
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Sensorerna köpte jag av någon här på forumet. Har inte sett dem på någon annat ställe. Jag kan lägga upp lite mer info (bla källkoden) senare, men det tar nog någon dag. Nogrannhet och dyligt kan jag inte uttala mig om riktigt än. Jag vet att den drar sig lite, kanske 1Ah per dygn på den ena sensorn. Jag har inte kalibrerat för sensorernas olikheter utan bara omvandlat enligt databladet.
barnie82se
Inlägg: 49
Blev medlem: 7 augusti 2005, 15:01:30

Inlägg av barnie82se »

Jätteintressant projekt!

Undrar bara hur många ampere den klarar per kanal? Vet du det? Hade gärna velat se ritning och C-koden om det går för sig.
Edit: -inget :)
Tackar
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Sensorerna klarar mäta upp till +-50A, men den klarar en överström på det femdubbla. C-kod kommer, kanske schema med.
barnie82se
Inlägg: 49
Blev medlem: 7 augusti 2005, 15:01:30

Inlägg av barnie82se »

OJ! Det var ett snabbt svar! Jag kan dock inte hitta liknande sensorer... Har bara hunnit leta på elfa än iofs... Kan du inte fråga honom du köpte av var han hittade dem?
Tack!
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Jag har inte heller sett dem någon annan stans. Han hade fått dom från en fyndlåda tror jag. Det kanske går att höra med allegro om dom har några återförsäljare i närheten. Annars kanske det går att sampla?
Användarvisningsbild
gOry
Inlägg: 4844
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

Inlägg av gOry »

Ser bra ut.

Har liknade i vår segelbåt, Byggd av en polare,
Den är rätt smart håller koll på allt möjligt så som startström laddning/urladdning, kan se ifall jag kan fixa lite bilder på den.
En sak som den har är tid kvar till 40% kan va bra att ha koll på. Har även ingångar för nivåmätning för färskvatten/diesel.
Användarvisningsbild
EagleSpirit
Inlägg: 1288
Blev medlem: 27 maj 2003, 23:15:48
Ort: Västerås
Kontakt:

Inlägg av EagleSpirit »

gOry: Skulle gärna vilja ha lite mer information om den där nivåmätningen.

simon78: Har du fixat så att de är lite noggrannare nu? Funderar lite på samma lösning men vill veta om det går att fixa till kalibreringen enkelt. Annars kanske det är lättare att köra med shuntmotståndsvarianten.
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Ja... jag har funderat lite på nogranheten och kalibreringen.... Som det är nu har jag bara räknat ut en omvandlingsfaktor från ADCn till A. Jag har gjort det med räta linjens ekvation ur grafen i databladet. Det blir inte helt optimalt. Jag försökte göra en funktionsanpassning. Tyckte att grafen såg ut att vara väldigt lik en sigmoid eller logistisk funktion eller vad man behagar att kalla den. Men anpassningen blev inget vidare.

Bild

Helst skulle man ju för varje givare ta ett 15-tal mätpunkter vid känd ström och använda ADC-värdena för kalibrering. Man kan ju enklast kanske köra räta linjer mellan dem, eller kanske en funktionsanpassning.

Möjligen blir det bättre med en shunt. Dessa givare fluktuerar ganska mycket (tror det är givarna iallafall). De ligger ganska bra runt medel, men det kan skilja +-0.02A per mätning. Inte mycket kanske, men det gör att den integrerade förbrukningen "drar sig".
barnie82se
Inlägg: 49
Blev medlem: 7 augusti 2005, 15:01:30

Inlägg av barnie82se »

Börja inte tvivla nu när jag fått tag i kretsarna kompis! 0.02A spelar väl ingen större roll när du har ett batteri på 80Ah? Du kan mäta fel i 80/0.02=4000 timmar typ. Räcker att man "nollar" varje gång man vet att batterierna är fulla så är det ju ok.

Det jag skulle säga var ivf att jag lyckades sampla 4st! Hur går det med C-koden förresten?
Tack å hej!
barnie82se
Inlägg: 49
Blev medlem: 7 augusti 2005, 15:01:30

Inlägg av barnie82se »

Hej igen! Jag funderade över dessa punkter:
1. Det här med att det hoppar mellan 0.02A, det kan ha att göra med att du måste skärma av din ATMega?! (Testa att koppla mätpinnen till Jord tex för att se om den blir stabil då...)
2. Vad använder du för referens när du använder ADC'n? Är den stabil?
3. AtMega88 klarar att mäta 0 till 5V i tio bitar. Alltså skillnaden på en bit blir ungefär 5mV. Detta motsvarar 0.125A enligt formeln nedan. Dessutom har ATMega88 +-2 LSB absolute accuracy vilket alltså blir +- 20mV => +-0.25A.
4. Om du inte skall mäta större strömmar än 50A så behöver du ju inte bry dig om hela grafen => Kollar man i grafen i databladet så är den ju linjär i mätområdet -50 till +50A. Denna formeln blir bäst: I = 25*U -62.5 Kan du inte testa det.

Kan du inte kommentera dessa pukter, tack
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Jag ska försöka ta en titt på det ikväll.
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

1. JAg har inte gjort några ansträgningar för att avskärma ADCn och höja tillförlitligheten på värdet där. Jag har bara kopplat en liten konding enligt strömmätarens datablad. Jag kunde ju säkert höjt nogrannheten genom att cadda ett bättre lämpat kort. Kanske man kunde låtit uP:n gått ner i ADC-läge, eller vad det kallas. Det kan finnas lite att vinna här faktiskt.
2. Referensen är Vcc. (om jag fattat rätt)
3&4. Du verkar ha lite rätt här. Jag funderar på hur jag har räknat i koden egentligen. Jag räknar ju till I från ADC så att säga.

Jag har inte tid att kolla igenom så jättenoga just nu (mätaren är i bruk och jag ska se på film) Jag klistrar in koden så länge så kan du kanske komma vidare lite. Tackar för dina kommentarer.

Kod: Markera allt


Ja, jag använder sprintf... jag vet men den är praktisk..

/*
*  C Implementation: main
*
* Description:
*
*
* Author: Simon Lundell <simon.lundell@his.se>, (C) 2006
*
* Copyright: See COPYING file that comes with this distribution
*
*/
#include "stdio.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "lcd/lcd.h"


#define RESET_DELAY_TICKS 100



#define RESET_BUTTON1_DDR     DDRB
#define RESET_BUTTON1_PORT    PORTB
#define RESET_BUTTON1_PIN     PINB
#define RESET_BUTTON1_PIN_ID  PB1

#define RESET_BUTTON2_DDR     DDRB
#define RESET_BUTTON2_PORT    PORTB
#define RESET_BUTTON2_PIN     PINB
#define RESET_BUTTON2_PIN_ID  PB2

static uint8_t reset_counter1;
static uint8_t reset_counter2;

/*************************************************************************
 delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
*************************************************************************/
static inline void _delayFourCycles(unsigned int __count)
{
   if ( __count == 0 )
      __asm__ __volatile__( "rjmp 1f\n 1:" );    // 2 cycles
   else
      __asm__ __volatile__ (
            "1: sbiw %0,1" "\n\t"
            "brne 1b"                              // 4 cycles/loop
   : "=w" (__count)
   : "0" (__count)
                           );
}


/*************************************************************************
delay for a minimum of <us> microseconds
the number of loops is calculated at compile-time from MCU clock frequency
*************************************************************************/
#define delay(us)  _delayFourCycles( ( ( 1*(F_CPU/4000) )*us)/1000 )



volatile static double centiamps_sens1;
volatile static double centiamps_sens2;
volatile static double centiamp_hours_sens1;
volatile static double centiamp_hours_sens2;

volatile static uint32_t irq_ticks_sens1;
volatile static uint32_t irq_ticks_sens2;



SIGNAL(SIG_OVERFLOW2){ //called continously

   ++irq_ticks_sens1;
   ++irq_ticks_sens2;
   if (bit_is_clear(RESET_BUTTON1_PIN, RESET_BUTTON1_PIN_ID)){
      if (reset_counter1++ > RESET_DELAY_TICKS){
         centiamp_hours_sens1=0;
      }
   } else{
      reset_counter1=0;
   }

   if (bit_is_clear(RESET_BUTTON2_PIN, RESET_BUTTON2_PIN_ID)){
      if (reset_counter2++ > RESET_DELAY_TICKS){
         centiamp_hours_sens2=0;
      }
   } else{
      reset_counter2=0;
   }
}

void inline init_timer2(){

   ASSR   |= _BV(AS2);  //Use external crystal as clock
   TCCR2B |= /*_BV(CS21) |*/ _BV(CS20); //prescaler 32 => 4/s (256 ticks between irqs)
   TIMSK2 |= _BV(TOIE2);  //Overflow interrupt enable

}


void adc_init(){
  PRR    &= ~_BV(PRADC);

  ADCSRA |=  _BV(ADEN);

  ADCSRA &= ~_BV(ADATE);
  ADMUX  &= ~_BV(ADLAR);

  ADCSRA &= ~_BV(ADIE);
  ADCSRA |= _BV(ADPS0) |_BV(ADPS1) |_BV(ADPS2); //slow but accurate, highest prescaler
}

void adc_select_sens1(){
   ADMUX &= ~_BV(MUX2) & ~_BV(MUX3);
   ADMUX |=  _BV(MUX0) |  _BV(MUX1);
}
void adc_select_sens2(){
   ADMUX &= ~_BV(MUX0) & ~_BV(MUX2) & ~_BV(MUX3);
   ADMUX |=  _BV(MUX1);
}

uint16_t adc_read(){


  ADMUX |=  _BV(REFS0);
  ADMUX &= ~_BV(REFS1);

//  ADCSRA |= _BV(ADIF);

  ADCSRA |= _BV(ADSC);

  while(bit_is_set(ADCSRA,ADSC));


  // CAUTION: MUST READ ADCL BEFORE ADCH!!!
  return (ADCL | ADCH<<8);  // read ADC (full 10 bits);

}
double adc_to_centiamps(uint16_t adc){
   if ((adc<102) || (adc>921))
      return ((double)adc-512.0)*24.90;
  else
     return ((double)adc-512.0)*12.20703125;
  //Taken from primari-A-to-voltage graph in datasheet
  // 204,8 ADC-bits / 2500 cA = 12.20703125
}



inline void update_display(){

   static char buffer1[16];
   static char buffer2[16];

   sprintf(buffer1,"%-+3.1fA    %-+3.1fA",centiamps_sens1/100.0,centiamps_sens2/100.0);
   sprintf(buffer2,"%-+3.2fAh  %-+3.2fAh",centiamp_hours_sens1/100.0,centiamp_hours_sens2/100.0);

   lcd_clrscr();
   lcd_puts(buffer1);
   lcd_gotoxy(0,1);
   lcd_puts(buffer2);


}



int main(){

   RESET_BUTTON1_DDR  &= ~_BV(RESET_BUTTON1_PIN_ID);
   RESET_BUTTON1_PORT |=  _BV(RESET_BUTTON1_PIN_ID);

   RESET_BUTTON2_DDR  &= ~_BV(RESET_BUTTON2_PIN_ID);
   RESET_BUTTON2_PORT |=  _BV(RESET_BUTTON2_PIN_ID);

   adc_init();
   init_timer2();
   sei();
   lcd_init(LCD_DISP_ON);



   static uint16_t adc;

   adc_select_sens1();
   adc = adc_read();
   centiamps_sens1 =  -adc_to_centiamps(adc);// - sign to correct for physical orientation of sensor

   adc_select_sens2();
   adc = adc_read();
   centiamps_sens2 =  +adc_to_centiamps(adc);// + sign to correct for physical orientation of sensor


   for (;;) {

      adc_select_sens1();
      adc = adc_read();
      centiamps_sens1 +=  (-adc_to_centiamps(adc)-centiamps_sens1)/30.0;// - sign to correct for physical orientation of sensor
      centiamp_hours_sens1 += (-adc_to_centiamps(adc)*irq_ticks_sens1)/460800.0;// - sign to correct for physical orientation of sensor
      irq_ticks_sens1=0;

      adc_select_sens2();
      adc = adc_read();
      centiamps_sens2 +=  (+adc_to_centiamps(adc)-centiamps_sens2)/30.0;// + sign to correct for physical orientation of sensor
      centiamp_hours_sens2 += (+adc_to_centiamps(adc)*irq_ticks_sens2)/460800.0;// + sign to correct for physical orientation of sensor
      irq_ticks_sens2=0;

      update_display();



   }

return 0;
}

Skriv svar