Loading...
Pages: [1] 2   Go Down
Author Topic: bis zu 7 Zahlen in den EEPROM schreiben ?  (Read 848 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo allerseits und frohe Weihnachten...
ich möchte gerne einen Wert der aus bis zu 7 Zahlen (float ZStandNeu) besteht in den EEPROM schreiben,
damit diese nicht nach Spannungsverlust oder Reset verloren gehen.

Code:
long ZStand = 898734;  // Zählerstand bei Start
float ZStandNeu;       // Neuer Zählerstand

Ist sowas möglich ? Und wenn JA,WIE ?  smiley-red

Hintergrund: Ich habe an meinem Gaszähler einen Reedkontakt, der jeden Impuls in eine SQL-Datenbank schreibt,
mit Datum und Uhrzeit, um damit Visuell den Verbrauch anzuzeigen.

Könnt Ihr mir bei dem Projekt behilflich sein ?
Bin noch nicht so lange mit dem Arduino vertraut.

Hier der Sketch, den ich z.Z. nutze, aber da ist der Zählerstand ja immer wieder der wie beim Start... smiley-fat
Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <Ethernet.h>             // library for ethernet functions

//ETHERNET-SETTINGS
byte mac[]     = { 0x5D, 0xA2, 0xFA, 0x2D, 0x76, 0x8C };    // MAC-Adresse des Arduino
byte ip[]      = { 192, 168, 178, 41 };                     // IP-Adresse des Arduino
byte gateway[] = { 192, 168, 178, 1 };                    // Gateway
byte subnet[]  = { 255, 255, 255, 0 };                    // SubNet
byte server[]  = { 192, 168, 178, 111 };                     // IP-Adresse des Servers

EthernetClient client;
char host[]    = "192.168.178.111";                      // Domain
char url[]     = "/Arduino/Gas/insert1.php"; // Pfad zur PHP-Datei
char key[]     = "ch5fn7sb";                     // Kennwort aus PHP-Datei

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
byte hoch3[8] = { B01110, B00010, B00110, B00010, B01110, B00000, B00000, B00000 };

int ReedPin = 8;     // Schalter ist mit Pin 8 verbunden
int PowerLED = 3;    // rote kontroll LED
int val;               // Variable für den Pin Zustand
int buttonState;       // Variable für den letzten Schalterzustand
int buttonPresses = 0; // Wie oft ist der Schalter gedrückt
long ZStand = 898734;      // Zählerstand bei Anschluss
float ZStandNeu;      // Zählerstand Neu

void setup()
{
   lcd.init(); // initialize the lcd
   lcd.backlight();
   lcd.createChar(0, hoch3);
   lcd.setCursor(8,1);
   lcd.print("m");
   lcd.setCursor(9,1);
   lcd.write(0);
   lcd.setCursor(0, 0);
   lcd.print("Gas-Zaehler");
  // warten, bis LAN gestartet
   Serial.begin(9600);
   pinMode(PowerLED, OUTPUT);
   pinMode(ReedPin, INPUT);
   Serial.println("Programm gestartet...");
   digitalWrite(ReedPin, HIGH);
   Serial.println(F("Ethernet initialisieren..."));
   Ethernet.begin(mac, ip);
   delay(5000);
   client.connect(server, 80);               // Verbindung zum Server aufbauen
   buttonState = digitalRead(ReedPin);  // Anfangszustand lesen
}

void loop()
{
val = digitalRead(ReedPin); // Eingabewert lesen und in val speichern
if (client.connected())
{
   Serial.println("Connected");
   Serial.println(digitalRead(ReedPin));
   if(val !=buttonState) {
     if (val == LOW) { // Ist der Schalter gedrückt?
       buttonPresses++; // Inkrementieren der Variablen buttonPresses,immer um 1 erhöhern
       Serial.print(F("Zählerstand "));
       ZStandNeu = ZStand + buttonPresses;
       Serial.print(ZStandNeu/100);
       Serial.print(" m");
       Serial.println(char(179));    // 179 = m³
       digitalWrite(PowerLED, LOW);
       lcd.clear();
       lcd.setCursor(8,1);
       lcd.print("m");
       lcd.setCursor(9,1);
       lcd.write(0);
       lcd.setCursor(0, 0);
       lcd.print("Gas-Zaehler");
       lcd.setCursor(0, 1);
       lcd.print(ZStandNeu/100);
       float gz = ZStandNeu/100; 
       Daten_senden(gz);
       delay(1000);
       client.flush();
       client.stop();
       }
       do
       {
           Serial.println("Warte bis Schalter wieder geloesst");
           delay(2000);
       } while ( !digitalRead(ReedPin) );
       client.connect(server, 80);
   }
   }else{
       Serial.println("NOT Connected");
       client.flush();
       delay(1000);
   }
   buttonState = val; // Den Zustand merken
}

void Daten_senden(float T1)
{
   if (client.connected())
   {
    Serial.println(F("Verbunden, Sende Daten..."));
    client.print("GET " + String(url));
    Serial.println("GET " + String(url));
    client.print(F("?T1="));
    Serial.print(F("?T1="));
    client.print(T1);
    Serial.println(T1);     
    client.print("&key=" + String(key));
    Serial.print("&key=" + String(key));
    client.println(" HTTP/1.1");
    Serial.println(F(" HTTP/1.1"));
    client.print("Host: " + String(host));
    Serial.print("Host: " + String(host));
    client.println();
    Serial.println();
    client.println("User-Agent: Arduino");
    Serial.println(F("User-Agent: Arduino"));
    client.println("Connection: close");
    Serial.println(F("Connection: close"));
    client.println();
    Serial.println();
   }
   else
   {
       Serial.println(" ***** VERBINDUNGSAUFBAU NICHT MÖGLICH *****");
       digitalWrite(PowerLED, HIGH);
       lcd.clear();
       lcd.setCursor(5, 0);
       lcd.print("Fehler!");
       lcd.setCursor(0, 1);
       lcd.print("Keine Verbindung");
       delay(5000);
   }
}
Ich bitte um Nachsicht, der Code ist noch nicht fertig Kommentiert und Aufgeräumt.

Danke


Logged

*greatz*

 CeTax

www dot blinkmann dot de


Alfeld (Leine) / Germany
Offline Offline
Full Member
***
Karma: 4
Posts: 155
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

-- Ohne den Code gelesen zu haben --

Der EEPROM kann nur begrenzt beschrieben werden.

Wäre es nicht sinnvoller a) den Zählerstand vorher aus der DB zu lesen? b) einfach nur pro Impuls eine Anfrage zum Höherzählen an die Datenbank zu geben?

Gruß,
Tobias
Logged

AREA COLOGNE
Offline Offline
God Member
*****
Karma: 12
Posts: 808
I am 1 of 10 who understands binary
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Du musst aus einem Long 4 Bytes machen
 
Code:
long ZStand = 898734;
byte Ebyte1=0;
byte Ebyte2=0;
byte Ebyte3=0;
byte Ebyte4=0;

             
 Ebyte1 = (int)((ZStand >> 24) & 0xFF) ;   
 Ebyte2 = (int)((ZStand >> 16) & 0xFF) ;
 Ebyte3 = (int)((ZStand >> 8) & 0XFF);
 Ebyte4 = (int)((Zstand & 0XFF));             


Die Ebytes in dem EEprom ablegen(aber nur bei änderung von einem der Bytes nur das veränderte Byte ablegen damit das EEProm nicht hops geht) und im Setup vor dem Start wieder lesen. Das müsste es sein
Meine infos sind von hier auch wieder zurück.
http://rclermont.blogspot.de/2010/02/convert-long-into-byte-array-in-cc.html
Logged

Eine Glatze ist wohl die AUSGEFALLENste Frisur von allen.

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Tobias,
Da habe ich auch gerade drüber nachgedacht, deine Variante A.
Aber da scheitere ich an meinem kleinen Wissen  smiley-red

-- Ohne den Code gelesen zu haben --

Der EEPROM kann nur begrenzt beschrieben werden.

Wäre es nicht sinnvoller a) den Zählerstand vorher aus der DB zu lesen? b) einfach nur pro Impuls eine Anfrage zum Höherzählen an die Datenbank zu geben?

Aber die Varinante B, wäre glaube ich schlauer...
Auch wegen der Visualisierung...

Danke für den Denkanstoß, werde erstmal LESEN gehen und mal sehen wie weit ich komme...

Aber für HIlfe für Variante A , wäre sehr Dankbar...
« Last Edit: December 26, 2012, 04:09:05 pm by Cetax » Logged

*greatz*

 CeTax

www dot blinkmann dot de


Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 162
Posts: 15729
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

2 Probleme:

Eine Float-Typ Variable als Zählerstand zu verwenden ist falsch. Eine Float Zahl kann zwar sehr große Zahlen darstellen aber nur mit begrenzter Genauigkeit. Die Genauigkeit ist auf 6-7 Stellen begrenzt. Wenn Du dann die Zahl um 1 erhöhst dann bleibt die Zahl gleich. Du mußt unsigned Long verwenden.

Du machst ausgiebig Gebrauch von Serial.print, LCD.print und client.print. All diese Funktionen brauchen RAM und dieses ist schnell mal voll und führt zu unvorhersagbaren Verhalten des Sketches. Verwende F() wie in http://arduino.cc/forum/index.php/topic,127552.msg965539.html#msg965539

Für die Zwischenspeicherung des Zählertandes kannst Du das RAM der RTC benutzen der DS1307 hat 56 Byte RAM batteriegepuffert.

Grüße Uwe
Logged

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Uwe,
ich hatte deinen Vorschlag/Hinweis ja schon teilweise umgesetzt  smiley-red
Habe ich jetzt aber ganz gemacht, alles in (F() gesetzt. Und die Serial Sachen fliegen sowieso raus, wenn er läuft.  smiley-cool

Und ich habe die Variable Float-Typ in unsigned long geändert.
Jetzt bekomme ich aber keinen Punkt mehr angezeigt  smiley-confuse
Vorher sah die Zahl z.B. so aus : 8536.25
Wurde auch so in die DB gespeichert. Jetzt sieht es so aus 853625.
Auch in der DB.... Gibt es dafür eine Lösung ? smiley-confuse

2 Probleme:

Eine Float-Typ Variable als Zählerstand zu verwenden ist falsch. Eine Float Zahl kann zwar sehr große Zahlen darstellen aber nur mit begrenzter Genauigkeit. Die Genauigkeit ist auf 6-7 Stellen begrenzt. Wenn Du dann die Zahl um 1 erhöhst dann bleibt die Zahl gleich. Du mußt unsigned Long verwenden.

Du machst ausgiebig Gebrauch von Serial.print, LCD.print und client.print. All diese Funktionen brauchen RAM und dieses ist schnell mal voll und führt zu unvorhersagbaren Verhalten des Sketches. Verwende F() wie in http://arduino.cc/forum/index.php/topic,127552.msg965539.html#msg965539

Für die Zwischenspeicherung des Zählertandes kannst Du das RAM der RTC benutzen der DS1307 hat 56 Byte RAM batteriegepuffert.

Ich habe keine RTC dran  smiley-confuse
Aber ein Ethernet-Shield mit SD Karten Slot, da könnte man doch auch speichern , oder ?

Die Variante, den letzten Stand aus der MySQL zu lesen finde ich aber glaube ich besser,
habe aber noch nix dazu gefunden, reinschreiben ja, aber nicht wie man aus der DB liest...
« Last Edit: December 26, 2012, 06:59:50 pm by Cetax » Logged

*greatz*

 CeTax

www dot blinkmann dot de


Alfeld (Leine) / Germany
Offline Offline
Full Member
***
Karma: 4
Posts: 155
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Cetax,

ich war der Meinung, der Code zum Auslesen und Schreiben der DB kam von dir...
Sei's drum.

Teil uns mal den Inhalt der Gas/insert1.php mit.
Dann kann ich dir gerne ein passendes Script zum Auslesen schicken^^

Gruß,
Tobias
Logged

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Tobias,
vielen Dank für deine schnelle Hilfe.

Quote
ich war der Meinung, der Code zum Auslesen und Schreiben der DB kam von dir...
Sei's drum.
Nee leider nicht, weiß nur einbischen wie man da was reinschreibt.  smiley-red

Quote
Teil uns mal den Inhalt der Gas/insert1.php mit.
Dann kann ich dir gerne ein passendes Script zum Auslesen schicken^^

Das wäre echt Super !!!
Hier der PHP-Code:
Code:
<?php

define
("KEY","123456");
 
include(
"db-config.php");
 
if(isset(
$_GET['key']))
{
  if(
$_GET['key'] == KEY)
  {
    if(isset(
$_GET['T1']))
    {
      
$GZ mysql_real_escape_string($_GET['T1']);
      
$DATUM date("Y-m-d H:i:s");
 
      
$result mysql_query("INSERT INTO Gas (datumzeit, GZStand)
              VALUES('"
.$DATUM."', '".$GZ."') ") or die(mysql_error());
 
      if(
mysql_affected_rows() == 1)
      {
        
$result "Gaswert gespeichert";
      } else 
$result "Fehler beim speichern der Daten in der MySQL-Datenbank";
    } else 
$result "Kein Wert &#252;bergeben";
  } else 
$result "Falscher Key";
} else 
$result "Kein Key &#252;bergeben";
 
print_r($result);
?>

Und der Code der db-config.php:
Code:
<?php
define
('DB_SERVER',"localhost");
define('DB_NAME',"Gas");
define('DB_USER',"stefan");
define('DB_PASSWORD',"123456");
 
$conn mysql_connect(DB_SERVERDB_USERDB_PASSWORD);
if(
is_resource($conn))
{
  
mysql_select_db(DB_NAME$conn);
  
mysql_query("SET NAMES 'utf8'"$conn);
  
mysql_query("SET CHARACTER SET 'utf8'"$conn);
}
else
echo 
"Fehler beim speichern der Daten in der MySQL-Datenbank";
?>
Ist ja fast wie Weihnachten... smiley-grin
« Last Edit: December 26, 2012, 07:22:58 pm by Cetax » Logged

*greatz*

 CeTax

www dot blinkmann dot de


Alfeld (Leine) / Germany
Offline Offline
Full Member
***
Karma: 4
Posts: 155
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Cetax,

etwas unschön ist die Tatsache, dass deine Tabelle keinen Primärschlüssel hat. (int - ID)

Das ganze müsste so funktionieren.

Probiere mit deinem Browser durch Aufruf von read1.php?key=123456 einmal, ob ein korrekter Wert zurückgegeben wird.

Code:
<?php

define
("KEY","123456");
 
include(
"db-config.php");
 
if(isset(
$_GET['key']))
{
  if(
$_GET['key'] == KEY//Key richtig?
  
{
    
//Von Tabelle Gas nehmen wir (sortiert nach datumzeit) das erste Element. 
$result mysql_query("SELECT * FROM Gas ORDER BY datumzeit DESC LIMIT 1") or die(mysql_error()); 

if(mysql_num_rows($result) == 1)
{
print_r(mysql_fetch_assoc($result)['GZStand']); //Lies die erste zurückgegebene Zeile ein, und gib dann GZStand aus.
} else $result "0"//Wenn noch nichts in der Datenbank steht, gib mal 0 zurück... 
  
} else $result "Falscher Key";
} else 
$result "Kein Key &#38;#252;bergeben";
 
print_r($result);
?>

Ist dies nicht der Fall, wäre es empfehlenswert, der Datenbank einen Selbst-Incrementierenden Primärschlüssel zu verpassen.
Der würde uns eine korrekte/bessere Sortierung ermöglichen.

Ich gehe stark davon aus, dass dieser Code NICHT funktionieren wird, da du das Datum als String/text in der Datenbank ablegst.
Das ist nicht gerade sauber, und verhindert (wie hier) dass man nach dem Datum korrekt sortieren kann...

Gruß,
Tobias (der müde ist und jetzt erstmal schlafen geht.. Gute Nacht!)
Logged

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Tobias,
nochmals Danke für deine Hilfe   smiley-kitty

Also habe deine Code getestet und wie du vermutet hast, kommt ne Fehlermeldung
Code:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, null given in /volume1/web/Arduino/Gas/in_puls1.php on line 16 Resource id #2

Ich verstehe aber nicht was ich an der DB ändern muss, damit ich einen Primärschlüssel (int - ID) bekomme
Quote
Ist dies nicht der Fall, wäre es empfehlenswert, der Datenbank einen Selbst-Incrementierenden Primärschlüssel zu verpassen.
Der würde uns eine korrekte/bessere Sortierung ermöglichen.

Ich habe mal 2 Bildschirmfotos gemacht, wie die DB aussieht:
https://dl.dropbox.com/u/80052077/Temp_Messung/SQL_Gas.png
https://dl.dropbox.com/u/80052077/Temp_Messung/SQL_Gas1.png

Das erste zeigt die Struktur und das zweite, den Inhalt.

Ich weiß das das nicht unbedingt mit ARDUINO zu tun hat, aber es ist ja für das Arduino-Projekt  smiley-red

Vielen Dank
Logged

*greatz*

 CeTax

www dot blinkmann dot de


Offline Offline
Edison Member
*
Karma: 18
Posts: 1297
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Cetax,
Du hast doch schon eine ID die auch noch auf AUTO_INCREMENT steht. Leider sieht man auf dem Bild nicht, ob diese Spalte der Tabelle auch noch der Primärschlüssel ist.
Logged

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Mario  smiley-mr-green

Quote
Du hast doch schon eine ID die auch noch auf AUTO_INCREMENT steht. Leider sieht man auf dem Bild nicht, ob diese Spalte der Tabelle auch noch der Primärschlüssel ist.

Ok, aber wo sieht man das denn ?
Von was soll ich ein Foto machen ?  smiley-red
Logged

*greatz*

 CeTax

www dot blinkmann dot de


Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, ich glaube ich habe da was gefunden...  smiley-kitty

https://dl.dropbox.com/u/80052077/Temp_Messung/SQL_Gas3.png

Ich bin auf Struktur und dann auf mehr, dort stand was von "Primärschlüssel hinzufügen" und
"Eindeutigen Index hinzufügen".
Das habe ich dann mal gemacht...

War das das was du meintest ?
Logged

*greatz*

 CeTax

www dot blinkmann dot de


Alfeld (Leine) / Germany
Offline Offline
Full Member
***
Karma: 4
Posts: 155
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Das ist doch schon wunderbar. Jetzt muss nur noch der PHP Code passend geändert werden.

Mach ich morgen smiley-razz
Logged

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Tobias,
 das ist ja GÖTTLICH....
Das ist doch schon wunderbar. Jetzt muss nur noch der PHP Code passend geändert werden.

Mach ich morgen smiley-razz

VIELEN DANK !! smiley-grin
Logged

*greatz*

 CeTax

www dot blinkmann dot de


Pages: [1] 2   Go Up
Print
 
Jump to: