Go Down

Topic: Serielles Signal aus werten (Waage-Projekt) (Read 8088 times) previous topic - next topic

MueThoS

Mar 13, 2011, 12:52 pm Last Edit: Mar 15, 2011, 06:05 pm by MueThoS Reason: 1
Hallo zusammen,
ich habe hier so eine Packetwage die einen seriellen Anschluss hat.
Jetzt hab ich mir überlegt, häng doch mal einen MC dran. Ich habe hier einen MEGA2560 rum liegen und habe über seriel1 eine Verbindung zur Waage hergestellt.
Seriel0 geht ja über den USB zum Rechner.
Dann habe ich aus einem anderen Beitrag folgenden Code übernommen:
Code: [Select]
void setup(){
 Serial.begin(2400);
 Serial1.begin(2400);
}

void loop(){
 if (Serial1.available() > 0) {
   Serial.println(Serial1.read());
 }
}


Dabei kam folgendes raus:
Code: [Select]

161
37
130
130
130
114
130
130
130
98
137
41
48
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
50
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
50
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
50
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
50
48
3
10
43
48
48
48
48
46
48
48
48
107
103
10
50
48
3
10
43
48
48
48
48
46
52
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
56
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
56
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
56
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
56
48
48
107
103
10
49
48
3
10
43
48
48
48
48
46
56
48
48
107
103
10
49
48
3
0
0
0
0
0
128

Gewicht was ich drauf gelegt habe waren 0,8 Kg
Klar, konnte natürlich nix mit anfangen.
Hab von Datenübertragung eigentlich keinen Plan.
Dann habe ich Google angeworfen und folgendes gefunden:
Quote
RS-232 interface protocol:
To transfer the weight value, unit and mode to computer via RS232.
When low battery, the above described action will not available.
Protocal:
ACHTUNG: Es gibt KEINEN Wägebefehl. Die Waage sendet STÄNDIG Daten.
BUAD RATE: 2400 bps
START BIT: 1 BIT
DATA BITS: 8 BITS
PARITY: NONE
STOP BITS: 1 BIT
DATA FORMAT:
Transmission Example
123.4kg
(OAH) (2BH) (30H) (31H) (32H) (33H) (2EH) (34H) (30H) (30H) (6BH) (67H)
LF + 0 1 2 3 . 4 0 0 k g
(OAH) (30H) (30H) (03H)
High-Order Byte Low-Order Byte 0Non zero-stable 0 Positive-non over load 1Non zero-non
stable 1 Negative-non over load2Zero-stable 2 Positive-over load 3Zero-non stable 3
Negative-over load
Each data is transfer 16 bytes (ASCII). The communication time of each data is about 450 m
Sec.
LF h h ETX
"LF" : Line Feed (ASCII=OAH)
"ETX" : End of Text (ASCII =03H)
"SIGH" : Can Be '+' or '-'
XXXX.XXX : Is the weight read by Scale (7 weights Data Byte)
UNIT : Can Be 'lb' or 'kg'
hh : Is a two byte Scale status hex code, as described below:
High-Order Byte: Low-Order Byte:
Bit 0: 0=Scale Stable Bit 0: 0=Scale is not under Capacity
1=Scale in motion 1=Scale is under Capacity
Bit 1: 0=Scale not at zero Bit 1: 0=Scale is not over Capacity
1=Scale at zero 1=Scale is over Capacity
Bit 2: Not Used Bit 2: Not Used
Bit 3: Not Used Bit 3: Not Used
Using D-TYPE 9 Pin Connector
Basic 4xx0 series RS-232C connections
(Miniumun Requirement Cable, End User)
Scale Cable Host
(Female) (Male) (Female) (Male)
NC 2 2----------------------3 3 TXD
TXD 3 3----------------------2 2 RXD
GND 5 5----------------------5 5 GND
+-------------4 +-4 4 DTR
+-------------6 +-6 6 TSR
+-------------8 +-8 8 CDS
Scale P4, 6, 8 Shorted

Kann mir da mal einer ein paar Tips für einen Anfänger geben wie ich das nu auswerten muss.

Ich will später eventuell die Daten mit einem UNO auswerten und per LAN-Shield direkt in eine mySQL schieben. (Wenn ich es denn hin bekomme).

Weiß nicht worauf ich achten muss bzw wonach ich suchen muss um meinem vorhaben näher zu kommen.
Tips und Suchbegriffe währen schon mal TOP.

Gruß
MueThoS

sth77

Okay, einen kleinen Denkanstoß kann ich dir geben, schau dir mal 'ne ASCII-Tabelle an. Nehmen wir nun einen Datenblock vom Anfang:

10 - LF
43 - +
48 - 0
48 - 0
48 - 0
48 - 0
46 - .
48 - 0
48 - 0
48 - 0
107 - k
103 - g
10 - LF
49 - 1
48 - 0
3 - ETX

Und nun noch einen von weiter hinten:

10 - LF
43 - +
48 - 0
48 - 0
48 - 0
48 - 0
46 - .
56 - 8
48 - 0
48 - 0
107 - k
103 - g
10 - LF
49 - 1
48 - 0
3 - EXT

Also würde ich erst einmal behaupten, dass deine Waage zum einen funktioniert und zum zweiten auch hinreichend genau misst. Du musst also die anfallenden Daten auswerten, um einen gültigen Wert zu bekommen. Hier kann man gezielt nach den "kg" triggern und die vorhergehenden 7 Stellen auswerten. Klingt nach einem spannenden Projekt!
Mein verwaister Arduino-Blog: http://www.sth77.de/ - letzter Eintrag: Diamex-ISP in der irgendwann mal aktuellen Arduino-IDE 1.6.4

MueThoS

Danke für die schnelle Antwort.
Ah, das sieht gut aus.
Also lese ich das nacheinander ein und muss zB bei 3=ETX nen neuen Datensatz anfangen.

Was aber wohl auch noch drinne ist:
Eine Anzeige ob die Werte schwanken:
Quote
High-Order Byte: Low-Order Byte:
Bit 0: 0=Scale Stable Bit 0: 0=Scale is not under Capacity
1=Scale in motion 1=Scale is under Capacity
Bit 1: 0=Scale not at zero Bit 1: 0=Scale is not over Capacity
1=Scale at zero 1=Scale is over Capacity

Aber gut
Ich werde also erstmal versuchen die Sachen auszuwerten die mir klar erscheinen.
Danke schon mal jetzt kann ich erstmal ein bisschen rum Coden und versuche einen vernünftigen String oder Array zu bilden.

MueThoS

#3
Mar 13, 2011, 02:38 pm Last Edit: Mar 13, 2011, 02:47 pm by MueThoS Reason: 1
So, hab mal rum gespielt:
Code: [Select]
void setup(){
 Serial.begin(2400);
 Serial1.begin(2400);
}

void loop(){
 if (Serial1.available() > 0) {
   char test = Serial1.read();
   switch(test){
     case 10:
       Serial.print("LF");
      break;
     case 43:
       Serial.print("+");
      break;
     case 45:
       Serial.print("-");
      break;
     case 46:
       Serial.print(".");
      break;
     case 48:
       Serial.print("0");
      break;
     case 49:
       Serial.print("1");
      break;
     case 50:
       Serial.print("2");
      break;
     case 51:
       Serial.print("3");
      break;
     case 52:
       Serial.print("4");
      break;
     case 53:
       Serial.print("5");
      break;
     case 54:
       Serial.print("6");
      break;
     case 55:
       Serial.print("7");
      break;
     case 56:
       Serial.print("8");
      break;
     case 57:
       Serial.print("9");
     break;
    case 107:
      Serial.print("k");
     break;
    case 103:
      Serial.print("g");
     break;
    case 108:
      Serial.print("l");
     break;
    case 98:
      Serial.print("b");
     break;
    case 3:
      Serial.println("ETX");
     break;
    default:
     Serial.print(test);
   }
 }
}


Ergebnis:
Quote

LF+0000.000kgLF10ETX <- Waage eingeschaltet mit nem Koffer drauf
LF+0000.000kgLF10ETX
LF+0000.000kgLF20ETX
LF-0003.800kgLF11ETX <- Koffer runter genommen - Wert
LF-0007.600kgLF11ETX
LF-0007.800kgLF11ETX
LF-0017.000lbLF01ETX <- umgestellt auf lb
LF-0017.000lbLF01ETX
LF-0017.000lbLF01ETX
LF-0007.800kgLF01ETX <- umgestellt auf kg
LF-0007.800kgLF01ETX
LF+0000.000kgLF20ETX <- tara gedrückt
LF+0000.000kgLF20ETX
LF+0000.000kgLF20ETX
LF+0000.600kgLF10ETX <- Koffer drauf gestellt
LF+0004.200kgLF10ETX
LF+0007.400kgLF10ETX
LF+0007.800kgLF10ETX
LF+0007.800kgLF10ETX


Jetzt muß ich das ganze in ein array packen und wenn das eine BIT :
Bit 0: 0=Scale Stable
Anzeigt dann ist der Wert ok und kann verwendet werden.

Oder über sehe ich was?


Edit:
Da muss ich noch mal Frage:
Mit den 2 Bits.

Quote

High-Order Byte:                         Low-Order Byte:
Bit 0: 0=Scale Stable                    Bit 0: 0=Scale is not under Capacity
        1=Scale in motion                        1=Scale is under Capacity
Bit 1: 0=Scale not at zero Bit            1: 0=Scale is not over Capacity
         1=Scale at zero                           1=Scale is over Capacity
Bit 2: Not Used Bit 2: Not Used
Bit 3: Not Used Bit 3: Not Used


Was meinen die genau mit High-Order und Low-Order?
Und wieso habe ich auch mal eine 2 die hier gar nicht erwähnt ist

MueThoS

Ich brauche noch mal Hilfe!

Und zwar versuche ich gerade mein char Array in ein int umzuwandeln.
Weiß aber nicht genau wie ich vorgehen muss.
Hab was von atoi gelesen finde aber keine Reference dazu.

Mein Code:
Code: [Select]
void loop(){
  if (Serial1.available() > 0) {
    data[i] = Serial1.read();
    if (data[i]==3){
      i=0;
      if (data[13]==48){
        int x;
        for (x = 3; x < 7; x = x + 1) {
         gewicht = gewicht & data[x];
        }
      }
    }else{
      i++;
    }
  }
  if (gewicht){
  Serial.println(gewicht);
  gewicht=0;
  }
}


Zwei Probleme/Fehler sind da drinne!
1. gewicht = gewicht & data
  • geht so nicht, war nur ein Test
    2. if (gewicht) geht auch nicht wollte eigentlich != "" haben aber da wird auch gemeckert. Bei PHP geht das 8-)

uwefed

Ok PHP ist nicht C oder C++
atoi() ist eine standart c Funktion. Die relative Bibliothek ist bereits standartmäßig includiert.
Ein String ist ein array von char mit einer null am Ende.
also zb 1, 2 , 3, 4, null .
Da das Gewict eine Dezimalzahl ist mußt Du:
* atof ( array to float) oder
* den Dezimalpunkt wegstreichen und in g rechnen ( achtung ein Int kann nur bis ca +/-32000 groß sein
 
Du kopierst die Chars der Zahl in ein zweites Array und wandelst das in ein int.
statt "gewicht = gewicht & data
  • ;" schreibst Du "wert[x-3] = data
  • ;"
    dann wert[4] =0;   

    Grüße Uwe

MueThoS

Danke,
ich glaube das größte Problem was ich hatte das ich nicht wußte das ich hier float zu nehmen habe.

Folgendes habe ich jetzt:
Code: [Select]
char data[16];
int i=0;
char temp[6];
float gewicht;
void setup(){
  Serial.begin(2400);
  Serial1.begin(2400);
}

void loop(){
    if (Serial1.available() > 0) {
        data[i] = Serial1.read();
        if (data[i]==3){
            i=0;
            if (data[13]==48){
                int x;
                for (x = 3; x < 9; x++) {
                    temp[x-3] = data[x];
                }
                temp[5] = '\0';
                gewicht = atof(temp);
            }
        }else{
            i++;
        }
    }
    if (gewicht){
    Serial.println(gewicht);
    gewicht=0;
    }
}

Klappt super.
Immer wenn die Waage sagt das ein Gewicht gemessen ist und die Anzeige im mom still steht (also keine Schwankungen sind) wird mir das Gewicht ausgegeben.
Jetzt muss ich nur noch son LAN-Shield haben.
Hmm, mal sehen was ich da alles zusammen bestelle.

Und die Anbindung an die DB wird auch noch mal tricky.
Gibts dazu schon was?
Entweder direkt zugriff auf die DB oder
Ich könnte die Daten in der URL mit geben und ein PHP-Script dahinter hänger.

Muss ich mir nur überlegen wie ich Missbrauch ausschließe.

Gruß
MueThoS

uwefed

Hallo MueThoS
Mit dem LAN-Shield und Webserver kann ich Dir nicht weiterhelfen.
Quote
Ich könnte die Daten in der URL mit geben und ein PHP-Script dahinter hänger.

Ich kann Dir nur sagen daß PHP auf dem Servr läuft und nicht vom Browser interpretiert wird.
Grüße Uwe

MueThoS

Hmmm,
das PHP-Script hatte ich mir auch auf dem Server im Internet vorgestellt. Also der Server wo auch meine Datenbank schon liegt.

Ich müsste dann zB von meinem Arduino aus eine URL aufrufen die so aussehen könnte:
www.meineDomain.de/script.php?gewicht=85.7
Dann könnte das script.php welches auf dem Server liegt den rest machen.
Das Script währe für mich kein Problem. Die Frage ist kann ich das mit dem LAN-Shield machen.
Da hab ich keine Ahnung von. Eventuell muss ich mir zuerst mal die LIB von Twitter anschauen was die da machen.
Da werden ja Daten gesendet.
Das werde ich gleich mal tun.

Gruß
MueThoS

MueThoS

Gibt es eigentlich auch einen Shop der mehr wie 30% seines Angebotes auch auf Lager hat?
Watterott hat ja nichts da! Wer weiß wie lange man da warten muss bis die Sachen da sind.

Die könnten so viel Kohle an mir verdienen aber ...
Wo kauft Ihr ein?

Ah, und noch was:
Gibt es ein SEHR günstiges Ossi.
Ich weiß nicht ich will da nicht so viel für ausgeben.
Dachte so an dieses DSO Nano oder maximal das Quad.
Wieviel mHz muss das können um beim Arduino und Konsorten klar zu kommen.
Ich denke das ich das nicht soo oft brauchen werde, deshalb soll es nicht so teuer sein.



uwefed

Kommt darauf an; wenn Du die Taktfrequenz auch aufzeichnen willst brauchst Du eines mit 40MHz Grenzfrequenz. Ich weiß nicht wieviel MSps das entspricht.
Ansonsten die angebotenen billigen DSO haben 1 bis 2 M-Samples pro Sekunde.
Ein Vorschlag: gib ein bißchen mehr Geld aus und kaufe das Kit mit dem SMD- vorbestückten Platinen.
Grüße Uwe
 

MueThoS

#11
Mar 15, 2011, 08:54 pm Last Edit: Mar 15, 2011, 08:57 pm by MueThoS Reason: 1
Du meinst dies hier:
http://www.watterott.com/de/Digitales-Speicher-Oszilloskop-DSO-Bausatz-alle-SMD-Teile-bestueckt
Oder ein anderes?

Das macht mir keinen guten Eindruck.
Währe natürlich sehr günstig.

ps: Ist übrigens auch nicht lieferbar  :) Ok, nehme alles zurück und behaupte das Gegenteil! Die verbesserte Version währe lieferbar.

uwefed

Das neue Modell hat das alte ersetzt.
Grüße Uwe

MueThoS

Jungs, ich brauche eure Hilfe!!!!

Ich komme einfach nicht damit klar was von Seriel kommt und was ich raus geben kann.
Kurz zur Wiederholung:
Mit folgendem Code lese ich meine Waage aus:
Code: [Select]
if (Serial.available() > 0) {
        data[i] = Serial.read();
        if (data[i]==3){
            i=0;
            if (data[13]==48){
                //int x;
                //for (x = 3; x < 9; x++) {
                //    temp[x-3] = data[x];
                //}
                //temp[5] = '\0';
                //gewicht = atof(temp);
            }
        }else{
            i++;
        }
    }

Das klappte ja auch soweit!

Wie man sieht hatte ich das data-Array noch mal gewandelt in ein float. und habe es dann ausgegeben auf den Seriellen Monitor.
Nun möchte ich folgendes machen:
Ich hatte einen MEGA dran und die Waage über Seriel1 ausgelesen.
Jetzt würde ich gerne mit dem UNO arbeiten.
Da ergeben sich folgende Probleme:

Kann ich die Waage am RX auslesen und mein serielles Display über den TX ansteuern.
Oder besser: Kann ich den SoftSeriel nehmen um die TX/RX1 frei zu lassen zum bespielen? (SoftSeriel kannte .available() nicht)

Ich kann den Float nicht mit Seriel.print ausgeben da kommt eine Fehlermeldung. Den data-Array will er irgendwie auch nicht.

Eine weitere Frage ist:
Welche Pinne benutzt das Ethernet-Shield? War das 10,11,12,13?
Damit ich mir da nicht in die quere komme.

Ich stehe im mom total auf dem Schlauch.
Ich brauche das gemessene Gewicht eigentlich als Zahl (float) und als char fürs Display, glaube ich zumindest.
Quelle ist ein Array wo ich nicht genau weiß was drin ist. (also was das für ein Typ ist)
Gebe ich es an den Serielmonitor zeigt er mir eine schöne Zahl.
Will ich es aber auswerten muss ich den ASCI-Code nehmen.

Ohhh, ich habe Kopfschmerzen....

Go Up