Forum: Mikrocontroller und Digitale Elektronik Powermessung mit INA219


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Peter (Gast)


Lesenswert?

Da jetzt die Messung der Spannung und Strom mit dem INA219 geht, wollte 
ich auch Power messen und Anzeigen lassen. Die Spannung messe ich so:
1
// Spannungsmessung
2
    i2c_start(adr_ina219);          // Angabe Adresse
3
    i2c_write(0x02);              // Register Spannung
4
    i2c_stop();
5
    i2c_start(adr_ina219 +1);        // Auslesen Adresse + 1
6
    msb_spannung = i2c_readAck();      //...speichere oberes Bit
7
    lsb_spannung = i2c_readNak();      //...speichere unteres Bit
8
    i2c_stop();
9
    spannung_wrd = (msb_spannung << 8 | lsb_spannung);  // Zusammensetzung von o. & u. Byte
10
    spannung_anz = spannung_wrd / 2;    // Wert Spannung / 2
Im Datenblatt ist das register 0x03 für Power angegeben. Dazu wollte das 
Stück verwenden:
1
// Powermessung
2
    i2c_start(adr_ina219);      // Angabe Adresse
3
    i2c_write(0x03);          // Power
4
    i2c_stop();
5
    i2c_start(adr_ina219 +1);    // Auslesen Adresse + 1
6
    msb_power = i2c_readAck();    //...speichere oberes Bit
7
    lsb_power = i2c_readNak();    //...speichere unteres Bit
8
    i2c_stop();
9
    power_wrd = (msb_power << 8 | lsb_power);  // Zusammensetzung von o. & u. Byte
Bekomme immer 0 als Ergebnis angezeigt. Da mach woll was falsch. Jemand 
eine Idee dazu?

LG Pt

von Cyblord -. (cyblord)


Lesenswert?

Shunt eingestellt?

Strom wird wirklich korrekt gemessen?

von Peter (Gast)


Lesenswert?

Nach Angabe des Herstellers kann der INA219 ohne Einstellung verwendet 
werden. Auf der kleinen Platine ist ein Widerstand als SMD drauf. Die 
Spannung und der Strom wird korrekt angezeigt. Habe es mit einem 
externen Messgerät verglichen. Anzeigen entsprechen der wirklichen 
Messung. Es werden auch kein anderen Anzeigen gemacht oder falsche Werte 
für Power angezeigt.

von Karl M. (Gast)


Lesenswert?

Hallo Peter,

das Verhalten, steht doch im Datenblatt, RFM.
*8.5 Programming*
/An important aspect of the INA219 device is that it measure current or 
power if it is programmed based on the system. The device measures both 
the differential voltage applied between the IN+ and IN- input pins and 
the voltage at IN- pin. In order for the device to report both current 
and power values, the user must program the resolution of the Current 
Register (04h) and the value of the shunt resistor (RSHUNT) present in 
the application to develop the differential voltage applied between the 
input pins. Both the Current_LSB and shunt resistor value are used in 
the calculation of the Calibration Register value that the device uses 
to calculate the corresponding current and power values based on the 
measured shunt and bus voltages.

After programming the Calibration Register, the Current Register (04h) 
and Power Register (03h) update accordingly based on the corresponding 
shunt voltage and bus voltage measurements. Until the Calibration 
Register is programmed, the Current Register (04h) and Power Register 
(03h) remain at zero./

von Karl M. (Gast)


Lesenswert?

Hallo Peter,

schaut man erneut in das Datenblatt, sieht man unter 8.6.1 Register 
Information, dann die Register mit der Anmerkung (2) immer als Null 
gelesen werden.

Wer nun denkt, man muss da nicht einstellen, der irrt!
*8.6.1 Register Information*
/(2) The Power register and Current register default to 0 because the 
Calibration register defaults to 0, yielding a zero current value until 
the Calibration register is programmed./

von Karl M. (Gast)


Lesenswert?

Hallo Peter,

im Beitrag Beitrag "Anzeige mit INA219 schwankt um den Nullpunkt",
liest Du nur das INA219 Register 01, das ist nicht der Strom, sondern 
die Shuntspannung aus.

von Tom (Gast)


Lesenswert?

Peter schrieb:
> // Powermessung
>     i2c_start(adr_ina219);      // Angabe Adresse
>     i2c_write(0x03);          // Power
>     i2c_stop();
>     i2c_start(adr_ina219 +1);    // Auslesen Adresse + 1
>     msb_power = i2c_readAck();    //...speichere oberes Bit
>     lsb_power = i2c_readNak();    //...speichere unteres Bit
>     i2c_stop();
>     power_wrd = (msb_power << 8 | lsb_power);  // Zusammensetzung von o.
> & u. Byte

Mal unabhängig vom eigentlichen Problem: Warum strukturierst Du Deinen 
Code nicht sinnvoll?

Das Auslesen von Registerwerten scheint ja immer nach dem gleichem 
Schema zu verlaufen. Das lohnt sich eine eigene Funktion, z.B.:
1
uint16_t ina219_read( uint8_t adr_ina219, uint8_t reg)
2
{   
3
    uint16_t value;
4
5
    i2c_start(adr_ina219);      // Angabe Adresse
6
    i2c_write(reg);
7
    i2c_stop();
8
    i2c_start(adr_ina219 +1);   // Auslesen Adresse + 1
9
    value  = i2c_readAck();     //...speichere oberes Byte
10
    value  = value << 8;
11
    value |=  i2c_readNak();    //...speichere unteres Byte
12
    i2c_stop();
13
    return value;
14
}

Zusammen mit ein paar netten defines:
1
#define INA_SHUNT_REG   0x01
2
#define INA_VOLTAGE_REG 0x02
3
#define INA_POWER_REG   0x03
4
#define INA_CURRENT_REG 0x04

...sieht das Auslesen gleich viel netter aus:
1
    spannung_wrd = ina219_read( adr_ina219, INA_VOLTAGE_REG);
2
    spannung_anz = spannung_wrd / 2;    // Wert Spannung / 2
3
    power_wrd    = ina219_read( adr_ina219, INA_POWER_REG);

Da macht dann auch das Debuggen mehr Spaß...

von Peter (Gast)


Lesenswert?

Hallo Tom
Danke für deinen Code.
Eigentlich ist das ganze Projekt so geplant (immer gleiche Hardware)

1. Inbetreibnahme einfach und Anzeige LCD (alle Funktionen und lesen 
I2C)
2. Setzen der Register für unterschiedlicher Auflösung z.B. 16V 200mA
3. Bedienung mit Drehgeber für Auswahl der Bereiche (Einknopfbedienung)
4. Eingabe Kalibrierung

Da passt dein Code sehr gut dazu. Für den Rest ist noch genug zu machen.

LG Pt

von Peter (Gast)


Lesenswert?

Karl M. schrieb:
> schaut man erneut in das Datenblatt, sieht man unter 8.6.1 Register
> Information, dann die Register mit der Anmerkung (2) immer als Null
> gelesen werden.
>
> Wer nun denkt, man muss da nicht einstellen, der irrt!
> *8.6.1 Register Information*
> /(2) The Power register and Current register default to 0 because the
> Calibration register defaults to 0, yielding a zero current value until
> the Calibration register is programmed./

Hallo Karl
das Stück hatte ich leider überlesen. Wenn ich das richtig verstanden 
habe, steht das Register der Powermessung beim Einschalten immer auf 0 
bis das Kalibrierregister programmiert ist. Nach meinem Plan sollte das 
aber erst später kommen. Dann werde ich das mal vorziehen. Bleibt nur 
die Frage wie mach ich das?

LG PT

von Cyblord -. (cyblord)


Lesenswert?

Peter schrieb:
> Dann werde ich das mal vorziehen. Bleibt nur
> die Frage wie mach ich das?

Es gibt zwei Möglichkeiten:

1.) Man muss raten.
2.) Es steht im Datenblatt.

Was denkst du welche Möglichkeit die wahrscheinlichere ist?

Es gibt eine Formel im DB in die man den verwendeten Shunt einsetzt und 
dann fällt da ein Registerwert raus. Den trägt man ein. Dann kann der 
INA den Strom und damit auch Leistung messen.

Es sollte dir doch klar sein dass der INA nicht wissen kann was für 
einen Shunt du genau einsetzt oder? Und das er somit niemals den 
korrekten Strom anzeigen kann bevor du ihm das nicht mitgeteilt hast? 
Ja? Nein?

Kannst du dir nicht mal angewöhnen das scheiß PDF einfach mal ordentlich 
zu lesen. Anstatt immer nur widerwillig einen Absatz wenn es hoch kommt.
Da steht auch viel erklärende Prosa. Warum müssen das andere für dich 
tun?

Und falls es noch nicht klar ist: Eine fertige Platine ersetzt diesen 
Vorgang nicht. Der INA kann nicht vorprogrammiert werden. Du musst alle 
Einstellungen selbst vornehmen. Das nimmt dir kein "Hersteller" ab. Das 
nur weil du immer darauf rumreitetest du hättest eine fertige Platine 
gekauft.

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Hoffe das ich das PDF jetzt richtig gelesen habe.
Einstellung Konfigirationsregister, Beispiel:

0000 00x1 1101 1111

16V, 40mV, 12 Bit, 8 Samples Mode

0011 10x0 0110 1111

32V, 320mV, 9 Bit, 32 Samples, Mode

Bleibt nur noch die übertragung zum INA. Wie kann ich diese relativ 
grosse Zahl übertragen?

von Karl M. (Gast)


Lesenswert?

Peter schrieb:
> Bleibt nur noch die übertragung zum INA. Wie kann ich diese relativ
> grosse Zahl übertragen?

Hallo,
nun das sind ja keine Zahlen...

Und keiner kann Dir ohne Schaltplan sagen, wie er die "Zahlen" berechnen 
würde.
In welchem Kontext stehen die "Zahlen".

Generell sagt/ zeigt Dir auch das Datenblatt, wie man über I2C Daten um 
INA219 übertragen muss.

Wie man nun eine 16 Bit Zahlen in MSB und LSB zerlegt, ist wider so ein 
"C Ding" - mit Schieben und Maskieren.

von Cyblord -. (cyblord)


Lesenswert?

Karl M. schrieb:
> Wie man nun eine 16 Bit Zahlen in MSB und LSB zerlegt, ist wider so ein
> "C Ding" - mit Schieben und Maskieren.

Vor allem bei Konstanten... Da musst du gar nichts machen.

Aber zum TE fällt mir nichts mehr ein.

von STK500-Besitzer (Gast)


Lesenswert?

Peter schrieb:
> Bleibt nur noch die übertragung zum INA. Wie kann ich diese relativ
> grosse Zahl übertragen?

I2C ist byteorientiert. Du musst deine "Words" in zwei Byte auftrennen 
und in der richtigen Reihenfolge an den Chip senden.

von Karl M. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Vor allem bei Konstanten... Da musst du gar nichts machen.

Ja korrekt, die Zerlegung kann jeder direkt ablesen, bis auf diese "X" 
...

von Peter (Gast)


Lesenswert?

Das x bedeutet "egal" nach DB.
Die Zahlen habe ich nicht berechnet, die stehen in einer Tabelle des 
Herstellers und sollen das Reg. einstellen. Dazu gibt es auch keinen 
Schaltplan. Die Werte geben an was der IC machen soll. Danach erfolgt 
erst die Berechnung.

Karl M. schrieb:
> Wie man nun eine 16 Bit Zahlen in MSB und LSB zerlegt, ist wider so ein
> "C Ding" - mit Schieben und Maskieren.

Das bedeutet das ich die 16 Bit Zahl in zwei 8 Bit verwandle und als MSB 
und LSB übertrage zum IC. Ist die reihenfolge beim senden genau so wie 
beim Empfang?

von Karl M. (Gast)


Lesenswert?

Hallo

Peter schrieb:
> Das bedeutet das ich die 16 Bit Zahl in zwei 8 Bit verwandle und als MSB
> und LSB übertrage zum IC. Ist die reihenfolge beim senden genau so wie
> beim Empfang?

Ja das liebe INA216 Datenblatt:

ich finde auf Seite 16 im Diagramm 15 das I2C Protokoll für  "Timing 
Diagram for Write Word Format".

Damit solltest Du, nach dem die Formel (1) unter 8.5.1 Programming the 
Calibration Register berechnet wurde, den passenden 16 Bit Wert für das 
Calibration Register.

von Karl M. (Gast)


Lesenswert?

Hallo Mitleser,

ein Suchsystem hat für den INA219 diese Webseite samt Beschreibung 
geliefert:

# 
https://learn.adafruit.com/adafruit-ina219-current-sensor-breakout?view=all

# 
https://cdn-learn.adafruit.com/downloads/pdf/adafruit-ina219-current-sensor-breakout.pdf

Weiter unten sehen wir dann diesen Schaltplan:

# 
https://cdn-learn.adafruit.com/assets/assets/000/036/267/original/adafruit_products_schem.png

Was wir von Peter (TO) bisher nicht gesehen haben, ist das gesamte 
Programm, um auf den INA216 zugreifen zu können.

von Peter (Gast)


Lesenswert?

Kein Problem kommt sofort. Steht leider noch eas drin was vielleicht 
nicht geht
1
#include <stdbool.h>
2
#include <avr/pgmspace.h>
3
#include "main.h"
4
#include <util/delay.h>
5
#include "i2clcd.h"
6
#include "i2cmaster.h"
7
#include "avr/io.h"
8
#include "util/delay.h"
9
#include "avr/interrupt.h"
10
#include "stdlib.h"
11
#include "INA219.h"
12
13
uint16_t msb_strom;              // Oberes Strom-Byte
14
uint16_t lsb_strom;              // Unteres Strom-Byte
15
uint16_t strom_wrd;             // Ganzes Strom-Wort
16
uint16_t strom_anz;             // Ganzes Strom-Anzeige
17
uint16_t strom_anz1;           // Ganzes Spannungs-Anzeige
18
uint16_t strom_anz2;           // Ganzes Spannungs-Anzeige
19
uint16_t strom_anz3;           // Ganzes Spannungs-Anzeige
20
uint16_t strom_anz4;           // Ganzes Spannungs-Anzeige
21
uint16_t strom_anz5;           // Ganzes Spannungs-Anzeige
22
uint16_t strom_anz6;           // Ganzes Spannungs-Anzeige
23
uint16_t strom_anz7;           // Ganzes Spannungs-Anzeige
24
25
uint16_t msb_spannung;            // Oberes Spannungs-Byte
26
uint16_t lsb_spannung;            // Unteres Spannungs-Byte
27
uint16_t spannung_wrd;           // Ganzes Spannungs-Wort
28
uint16_t spannung_anz;           // Ganzes Spannungs-Anzeige
29
uint16_t spannung_anz1;           // Ganzes Spannungs-Anzeige
30
uint16_t spannung_anz2;           // Ganzes Spannungs-Anzeige
31
uint16_t spannung_anz3;           // Ganzes Spannungs-Anzeige
32
uint16_t spannung_anz4;           // Ganzes Spannungs-Anzeige
33
uint16_t spannung_anz5;           // Ganzes Spannungs-Anzeige
34
uint16_t spannung_anz6;           // Ganzes Spannungs-Anzeige
35
uint16_t spannung_anz7;           // Ganzes Spannungs-Anzeige
36
37
uint16_t msb_power;              // Oberes Power-Byte
38
uint16_t lsb_power;              // Unteres Power-Byte
39
uint16_t power_wrd;             // Ganzes Power-Wort
40
uint16_t power_anz;             // Ganzes Power-Anzeige
41
42
uint8_t ret;                   // Kontrollvariable für I2C Kommunik.
43
uint8_t x;                     // X-Position der Kommastelle
44
signed char strom;          // Variable m. Vorzeichen für die Temp.berechnung
45
char Buffer[30];               // Umwandlungs-Variable für LCD Anzeige
46
47
#define adr_ina219 0x80         // Adresse des INA219 0x81
48
#define con_var 0x01DF 
49
//#define con_var 0x0386F
50
51
52
void anzeige_1(void)        // Anzeuîge erster Text
53
  {
54
    lcd_printlc(1,2,"Strommessung");     // Zeile 1
55
    lcd_printlc(2,3,"Programm 1");      // Zeile 2
56
    lcd_printlc(3,1,"mit INA219 Modul");  // Zeile 3
57
    lcd_printlc(4,2,"(vvvvvvvvvvv)");    // Zeile 4
58
  }
59
60
void anzeige_2(void)        // Anzeuîge zweiter Text
61
{
62
  lcd_printlc(1,2,"Daten Modul:");   // Zeile 1
63
  
64
  lcd_printlc(2,2,"Strom:");      // Zeile 2
65
  lcd_printlc(2,15,"mA");        // Zeile 2
66
  
67
  lcd_printlc(3,1,"Spang.:");      // Zeile 3
68
  lcd_printlc(3,16,"V");        // Zeile 3
69
  lcd_printlc(3,11,",");        // Zeile 3
70
  lcd_printlc(4,1,"Leisg.:");      // Zeile 4
71
}
72
73
74
75
76
void stromfassung(void)
77
  {
78
  ret = i2c_start(adr_ina219);          // Start Lesen
79
  if (ret == 0)
80
    {                         // Wenn IC ein OK sendet...
81
    msb_strom = i2c_readAck();    //...speichere oberes Bit
82
    lsb_strom = i2c_readNak();    //...speichere unteres Bit
83
    }
84
  else                                // Fehlererkennung
85
    {                              // Wenn LM75 kein OK sendet
86
    lcd_command(LCD_CLEAR);      // Leere Display
87
    _delay_ms(2);
88
    lcd_printlc(1,13,"READ");    // "Lesevorgang"
89
    lcd_printlc(2,13,"NOK");    // "Nicht OK (NOK)
90
    }
91
  }
92
93
int main(void)
94
{
95
  cli();                           // Interrupts deaktiviert
96
  i2c_init();                      // Starte I2C Bus$
97
  lcd_init();                      // Starte I2CLCD
98
  
99
  // Display Befehle
100
  lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
101
  
102
  lcd_command(LCD_CLEAR);            // Leere Display
103
  _delay_ms(2);                // Warte 2ms
104
  
105
  anzeige_1();
106
  
107
  _delay_ms(3000);
108
  
109
  lcd_command(LCD_CLEAR);          // Leere Display
110
  _delay_ms(2);                // Warte 2ms
111
  
112
  anzeige_2();
113
  
114
  _delay_ms(100);               // Warte 500ms
115
  
116
  
117
  i2c_start(adr_ina219);          // Angabe Adresse
118
  i2c_write(0x00);            // Register Spannung
119
  i2c_write (con_var >> 8);            // Register Spannung
120
  i2c_write(con_var & 0xFF );            // Register Spannung
121
  i2c_stop();
122
  
123
  
124
  //i2c_write( (con_var & 0xFF00) >> 8);                       // Register Spannung
125
  //i2c_write( con_var & 0x00FF )
126
  
127
  
128
  while(1)
129
    {
130
    stromfassung();                        // Unterprg Strom.auslesung
131
    
132
    // Strommessung
133
    i2c_start(adr_ina219);      // Angabe Adresse
134
    i2c_write(01);          // Strom
135
    i2c_stop();
136
    i2c_start(adr_ina219 +1);    // Auslesen Adresse + 1
137
    msb_strom = i2c_readAck();    //...speichere oberes Bit
138
    lsb_strom = i2c_readNak();    //...speichere unteres Bit
139
    i2c_stop();
140
    strom_wrd = (msb_strom << 8 | lsb_strom);  // Zusammensetzung von o. & u. Byte
141
    strom_anz = strom_wrd / 8;
142
    
143
    if (strom_anz == 8191) 
144
      {
145
        strom_anz = 0;
146
      }   
147
    
148
    utoa(strom_anz, Buffer, 10 );
149
    lcd_printlc(2,10,"     ");  
150
    lcd_printlc(2,11,Buffer);
151
    
152
    // Spannungsmessung
153
    i2c_start(adr_ina219);          // Angabe Adresse
154
    i2c_write(0x02);            // Register Spannung
155
    i2c_stop();
156
    i2c_start(adr_ina219 +1);        // Auslesen Adresse + 1
157
    msb_spannung = i2c_readAck();      //...speichere oberes Bit
158
    lsb_spannung = i2c_readNak();      //...speichere unteres Bit
159
    i2c_stop();
160
    spannung_wrd = (msb_spannung << 8 | lsb_spannung);  // Zusammensetzung von o. & u. Byte
161
    spannung_anz = spannung_wrd / 2;    // Wert Spannung / 2
162
    
163
    spannung_anz1 = spannung_anz % 10;    // 4. Zahl ok
164
    spannung_anz2 = spannung_anz / 10;
165
    spannung_anz3 = spannung_anz2 % 10;    // 3. Zahl
166
    spannung_anz4 = spannung_anz2 / 10;
167
    spannung_anz5 = spannung_anz4 % 10;    // 2. Zahl
168
    spannung_anz6 = spannung_anz4 / 10;
169
    spannung_anz7 = spannung_anz6 % 10;    // 1. Zahl
170
    
171
    itoa(spannung_anz7, Buffer, 10 );    // 1. Zahl
172
    lcd_printlc(3,10," ");
173
    lcd_printlc(3,10,Buffer);
174
    
175
    itoa(spannung_anz5, Buffer, 10 );    // 2. Zahl
176
    lcd_printlc(3,12," ");
177
    lcd_printlc(3,12,Buffer);
178
    
179
    itoa(spannung_anz3, Buffer, 10 );    // 3. Zahl
180
    lcd_printlc(3,13," ");
181
    lcd_printlc(3,13,Buffer);
182
    
183
    itoa(spannung_anz1, Buffer, 10 );    // 4. Zahl
184
    lcd_printlc(3,14," ");
185
    lcd_printlc(3,14,Buffer);
186
    
187
    
188
    // Powermessung
189
    i2c_start(adr_ina219);      // Angabe Adresse
190
    i2c_write(0x03);          // Power
191
    i2c_stop();
192
    i2c_start(adr_ina219 +1);    // Auslesen Adresse + 1
193
    msb_power = i2c_readAck();    //...speichere oberes Bit
194
    lsb_power = i2c_readNak();    //...speichere unteres Bit
195
    i2c_stop();
196
    power_wrd = (msb_power << 8 | lsb_power);  // Zusammensetzung von o. & u. Byte
197
    power_anz = power_wrd * 100;    // Wert Spannung / 2
198
    itoa(power_anz, Buffer, 10 );
199
    lcd_printlc(4,10,"     ");
200
    lcd_printlc(4,10,Buffer);
201
}}
Problem ist die übertragung des 16 Bit auf 2 x 8 Bit über I2C Bus

LG PT

von Peter (Gast)


Lesenswert?

Nach den angebenen Daten auf Seite 16 erfolgt

- Adresse
- MSB
- LSB

damit ist die reihenfolge der übertragung klar.
Bleibt noch die Formel auf Seite 12 Nr 1.
Die Eingabe von R Shunt ist klar. Bei meinem Teil sind 0,1 Ohm drin. Was 
trage ich für Current_LSB ein. Im Calb.  Register ist nicht vermerkt wo 
was steht.

von Manfred (Gast)


Lesenswert?

Irgendwas verstehe ich nun nicht mehr. Du bindest libraries ein
Peter schrieb:
> #include "i2cmaster.h"
> #include "INA219.h"

und willst trotzdem zu Fuß abfragen?

Die Adresse finde ich ungewöhnlich,
Peter schrieb:
> #define adr_ina219 0x80         // Adresse des INA219 0x81

sollte eher 0x40 sein?

von Peter (Gast)


Lesenswert?

Manfred schrieb:
> Irgendwas verstehe ich nun nicht mehr. Du bindest libraries ein
> Peter schrieb:
>> #include "i2cmaster.h"
>> #include "INA219.h"

Der i2cmaster wird für die übertragung aller Module verwendet. Stammt 
von Peter und verwende es in fast jedem Programm. die INA219 ist 
vorhanden, nutze sie aber noch nicht. Wenn die einzek^lnen Teile laufen 
wird dort hin einiges ausgelagert

von Manfred (Gast)


Lesenswert?

Peter schrieb:
> die INA219 ist vorhanden, nutze sie aber noch nicht.

Ehrgeiz oder Platzprobleme?

Ich habe gerade ein Projekt mit zwei INA219 durch, Arduino. Da frage ich 
die Library nach den Werten, bekomme sie geliefert und sehe keinerlei 
Grund, das selbst zu machen, ebenso wenig wie die Ansteuerung meines 
LCDs, der DA-Wandler und meiner SD-Karte ... ich habe genug eigenes Zeug 
drumherum.

von HJKastl (Gast)


Lesenswert?

Manfred schrieb:
> Ich habe gerade ein Projekt mit zwei INA219 durch, Arduino.

Hallo Manfred.
Ich probiere momentan 4 Ina219 in einem Arduino Mega Projekt mit 5 DHT22 
gemeinsam zum Laufen und zur Anzeige auf TFT zu bringen.
Als absoluter Anfänger wäre ich für funktionierende Beispiele dankbar, 
denn daran kann man am besten die Logik der Programmierung 
nachvollziehen und vielleicht begreifen.
Würdest Du den Code für deine 2 INA´s zur Verfügung stellen?
MfG
Hermann

von Karl M. (Gast)


Lesenswert?

Hallo,

ein INA219 oder weiter ist doch das selbe!
Jeder benötigt eine eigene I2C Adresse, dann lässt er sich adressieren 
und die Daten auswerten.

Zeig doch mal, was Du hast.

von Karl M. (Gast)


Lesenswert?

Hallo,

mal aus Interesse: für was brauchst Du INA219 ?
Wie sind die Beschaltet?

von HJKastl (Gast)


Lesenswert?

Hallo Kerl,
ich möchte mit 4 INA219 und 5 DHT22 und einem oder 2 Arduino Mega 2560 
vier Bordbatterien ( je 12V, 120AH) in einem WoMo über Relais 
überwachen, Ausgabe und Anzeige über TFT (UTFT).
Mein Problem dabei ist dass ich fast keine Ahnung im Programmieren habe 
und auf passende Beispiele angewiesen bin, die ich dann anzupassen 
versuche.
Beim Auslesen der Werte aus den 4 INAs und deren Anzeige auf dem TFT 
stecke ich momentan fest. Zwar zeigt der Serial Monitor die Werte an, 
aber wie bekomme ich diese für spätere Kapazitätsberechnungen 
gespeichert und in welcher Form kann ich diese am TFT anzeigen?
Gruß
Hermann

von HJKastl (Gast)


Lesenswert?

Hallo Karl,
hier mein bisheriges Programm dazu.
// BMS_WoMo
// zeigt 5 Temperaturen an
// UTFT_Demo_320x240 (C)2012 Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
//
// This program is a demo of how to use most of the functions
// of the library with a supported display modules.
//
// This demo was made for modules with a screen resolution
// of 320x240 pixels.
//
// This program requires the UTFT library.
// Das Original ist die UTFT.rar 2 607 889 von 2015/2016

#include <UTFT.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <Wire.h>
#include <Adafruit_INA219.h>

#define DHTPIN1 43
#define DHTPIN2 44
#define DHTPIN3 45
#define DHTPIN4 46
#define DHTPIN5 47

DHT dht[] = {               // Definition eiogene Klasse DHT22
  {DHTPIN1, DHT22},
  {DHTPIN2, DHT22},
  {DHTPIN3, DHT22},
  {DHTPIN4, DHT22},
  {DHTPIN5, DHT22},
};

Adafruit_INA219 ina219;
Adafruit_INA219 ina219_A(0x40);
Adafruit_INA219 ina219_B(0x41);
Adafruit_INA219 ina219_C(0x44);
Adafruit_INA219 ina219_D(0x45);



float temperature[4];
//#define DHTTYPE           DHT22
//DHT_Unified dht(DHTPIN, DHTTYPE);
//uint32_t delayMS;

// Declare which fonts we will be using
extern uint8_t SmallFont[];

// Uncomment the next line for Arduino Mega
UTFT myGLCD(ILI9327, 38, 39, 40, 41); // Remember to change the model 
parameter to suit your display module!
int temp;

void setup()
{
  Serial.begin(9600);
  for (auto& sensor : dht) {
    sensor.begin();
  }

  // dht.begin();
  // sensor_t sensor;
  // dht.temperature().getSensor(&sensor);

  randomSeed(analogRead(0));

  // Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(SmallFont);

  // Initialize the INA219.
  ina219.begin();
  ina219_A.begin();  // Initialize first board (default address 0x40)
  ina219_B.begin();  // Initialize second board with the address 0x41
  ina219_C.begin();  // Initialize second board with the address 0x44
  ina219_D.begin();  // Initialize second board with the address 0x45



  // Or to use a lower 16V, 400mA range (higher precision on volts and 
amps):
  ina219_A.setCalibration_16V_400mA();
  ina219_B.setCalibration_16V_400mA();
  ina219_C.setCalibration_16V_400mA();
  ina219_D.setCalibration_16V_400mA();

  Serial.println("Measuring voltage and current with INA219 ...");
}

void loop()
{
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);

  Serial.print("Bus Voltage:   "); Serial.print(busvoltage); 
Serial.println(" V");
  Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); 
Serial.println(" mV");
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); 
Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA); 
Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW); 
Serial.println(" mW");
  Serial.println("");




  for (int i = 0; i < 5; i++) {
    temperature[i] = dht[i].readTemperature();
  }

  for (int i = 0; i < 5; i++) {
    Serial.print(F("Temperature "));
    Serial.print(i);
    Serial.print(F("    "));
    Serial.print(temperature[i]);
    Serial.println(F("*C"));
  }

  delay(2000);

  //sensors_event_t event;
  //dht.temperature().getEvent(&event);
  //temp = dht.temperature().getEvent(&event) * 100;
  String tempe = "Temperature";
  //Serial.print(tempe);
  //Serial.print(temperature);
  String C = "*C";
  //
  int buf[318];
  int x, x2;
  int y, y2;
  int r;

  // Clear the screen and draw the frame
  // myGLCD.clrScr();

  myGLCD.setColor(255, 0, 0);// oberes Rechteck
  myGLCD.fillRect(0, 0, 319, 13);// Start x,y, Ende x,y
  myGLCD.setColor(64, 64, 64);// unteres Rechteck
  myGLCD.fillRect(0, 226, 319, 239);
  myGLCD.setColor(255, 255, 255);// Beschriftung oberes Feld weiß
  myGLCD.setBackColor(255, 0, 0);
  String BMS = "* BMS Wohnmobil *";
  myGLCD.print(BMS, CENTER, 1);
  myGLCD.printNumF(temperature[4], 0, 260, 1);
  myGLCD.print(C, 300, 1);         //hier steht der Wert des DHT22 PIN 5 
von Raumtemperatur


  myGLCD.setBackColor(64, 64, 64);// Beschriftungshintergrung unteres 
Feld
  myGLCD.setColor(255, 255, 0);
  String HJ = "HJKastl";
  myGLCD.print(HJ, CENTER, 227);

  myGLCD.setColor(0, 0, 255);// mittlere Fläche
  myGLCD.drawRect(0, 14, 319, 225);


  delay(2000);

  myGLCD.setColor(0, 0, 0);         //schwarz
  myGLCD.fillRect(1, 15, 318, 224); //ein Pixel kleiner als der Rahmen

  // Überschriftfeld für Batteriefelder

  // Überschriftfelder Text

  myGLCD.setColor(255, 255, 0);
  String Batt1 = "Batt 1";
  myGLCD.print(Batt1, 16, 16);


  myGLCD.setColor(255, 255, 0);
  String Batt2 = "Batt 2";
  myGLCD.print(Batt2, 96, 16);


  myGLCD.setColor(255, 255, 0);
  String Batt3 = "Batt 3";
  myGLCD.print(Batt3, 176, 16);

  myGLCD.setColor(255, 255, 0);
  String Batt4 = "Batt 4";
  myGLCD.print(Batt4, 256, 16);


  //Batteriesymbol Rahmen
  myGLCD.setColor(0, 0, 255);
  myGLCD.fillRect(21, 41, 59, 119);
  myGLCD.setColor(255, 255, 0);
  myGLCD.drawRect(20, 40, 60, 120);// Symbol Batt 1

  myGLCD.setColor(255, 255, 0);
  myGLCD.fillRect(101, 81, 139, 119);
  myGLCD.setColor(255, 255, 0);
  myGLCD.drawRect(100, 40, 140, 120);// Symbol Batt 2

  //myGLCD.setColor(255,0,0);
  //myGLCD.fillRect(179, 41, 219, 119);
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRect(180, 40, 220, 120);// Symbol Batt 3

  myGLCD.setColor(0, 255, 0);
  myGLCD.fillRect(261, 41, 299, 119);
  myGLCD.setColor(255, 255, 0);
  myGLCD.drawRect(260, 40, 300, 120);// Symbol Batt 4

  // Texte unter Batteriesymbolen
  myGLCD.setColor(255, 255, 0);
  myGLCD.print("13.75", 20, 130);// hier soll die Spannung stehen
  myGLCD.print("12.69", 100, 130);
  myGLCD.print("12.49", 180, 130);
  myGLCD.print("12.70", 260, 130);

  myGLCD.setColor(255, 255, 0);
  String V = "V";
  myGLCD.print (V, 60, 130);
  myGLCD.print(V, 140, 130);
  myGLCD.print(V, 220, 130);
  myGLCD.print(V, 300, 130);

  myGLCD.setColor(255, 255, 0);
  myGLCD.print("-12.7", 20, 150);//hier soll die Stromstärke stehen
  myGLCD.print("5.5", 100, 150);
  myGLCD.print("0.0", 180, 150);
  myGLCD.print("0.0", 260, 150);

  myGLCD.setColor(255, 255, 0);
  String A = "A";
  myGLCD.print(A, 60, 150);
  myGLCD.print(A, 140, 150);
  myGLCD.print(A, 220, 150);
  myGLCD.print(A, 300, 150);

  myGLCD.setColor(255, 255, 0);
  myGLCD.print("240", 20, 170);//hier soll die Kapazität stehen
  myGLCD.print("1200", 100, 170);
  myGLCD.print("2400", 180, 170);
  myGLCD.print("3600", 260, 170);

  myGLCD.setColor(255, 255, 0);
  String Wh = "Wh";
  myGLCD.print(Wh, 60, 170);
  myGLCD.print(Wh, 140, 170);
  myGLCD.print(Wh, 220, 170);
  myGLCD.print(Wh, 300, 170);

  myGLCD.setColor(255, 255, 0);
  for (int i = 0; i < 4; i++) {
    temperature[i] = dht[i].readTemperature();
  }

  // myGLCD.printNumF(event.temperature, 0, 20, 190);//hier steht der 
Wert des DHT22 von Batterie 1
  myGLCD.printNumF(temperature[0], 0, 20, 190);
  //myGLCD.print("30.7", 100, 190);                 //hier steht der 
Wert des DHT22 von Batterie 2
  myGLCD.printNumF(temperature[1], 0, 100, 190);
  //myGLCD.print("35.8", 180, 190);                 //hier steht der 
Wert des DHT22 von Batterie 3
  myGLCD.printNumF(temperature[2], 0, 180, 190);
  //myGLCD.print("45.0", 260, 190);                 //hier steht der 
Wert des DHT22 von Batterie 4
  myGLCD.printNumF(temperature[3], 0, 260, 190);


  myGLCD.setColor(255, 255, 0);                   //String C="*C"; wurde 
schon weiter oben erklärt
  myGLCD.print(C, 60, 190);
  myGLCD.print(C, 140, 190);
  myGLCD.print(C, 220, 190);
  myGLCD.print(C, 300, 190);

  myGLCD.setColor(255, 255, 0);
  String Laden = "Laden";
  myGLCD.print(Laden, 20, 210);
  String Betrieb = "Betrieb";
  myGLCD.print(Betrieb, 100, 210);
  String leer = "leer";
  myGLCD.print(leer, 180, 210);
  String voll = "voll";
  myGLCD.print(voll, 260, 210);
  //delay(1000);


}

von Weihnachtsmann (Gast)


Lesenswert?

Was meinst Du, wieso beim Klicken auf den Antworten-Button folgendes 
erscheint:

************************************************
Wichtige Regeln - erst lesen, dann posten!

    Groß- und Kleinschreibung verwenden
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

1
C-Code
[...]
************************************************

Eine Idee?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.