Go Down

Topic: Smart Meter - SML HEX Code zerlegen (Read 2209 times) previous topic - next topic

Doc_Arduino

Hallo,

Slaven, kannst mal mit 3 Datenpaketen zeigen wie das ganze zeitlich abläuft, damit ich einmal die Längen und Pausenzeiten einsehen kann? Log vom Wireshark sollte dafür reichen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

thorstengehrig

Hi
gibt es denn einen finalen Code der bei dir Läuft.
Ich habe heute 2 Stück MT175 bekommen und muss auch meinen alten Code umbauen (der noch kein SML war)
Gruß
Thorsten

jochen1981

Hallo,

ich hänge mich hier mal mit dran.

mit dem gezeigten Code habe ich mir was zusammengebastelt das mir an einem Pin ein 0-5V Signal erzeugt um einen Wechselrichter zu steuern.

Leider hab ich 0 Erfahrung mit Programmieren.

Ein Problem gild es noch in dem Code zu lösen , mal abgesehen vom Durcheinander:

Wenn keine Daten eindrudeln MUSS der Ausgang 0V haben, um zu verhindern das bei einem Fehler ggf. mit Voller LEistung eingespeist wird.

zusätzlich scheint der Code ztw zu hängen ??

evtl kann mir da jemand helfen?

Code: [Select]
byte inByte; //byte to store the serial buffer
byte smlMessage[1000];
const byte startSequence[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01 };//start sequence of SML protocol
const byte stopSequence[]  = { 0x1B, 0x1B, 0x1B, 0x1B, 0x1A };//end sequence of SML protocol
const byte powerSequence[] = { 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55 }; //sequence preceeding the current "Wirkleistung" value (4 Bytes)
int smlIndex;//index counter within smlMessage array
int startIndex;//start index for start sequence search
int stopIndex;//start index for stop sequence search
int stage;//index to maneuver through cases
int currentpower; //variable to hold translated "Wirkleistung" value
int currentpower1;
byte analogpower; //Byte für analogen Ausgang
byte power[4]; //array that holds the extracted 4 byte "Wirkleistung" value

void setup() {
  pinMode(9,OUTPUT);//setze PIN 9 für Output
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
     }
void loop() {
 
  switch (stage) {
    case 0:
      findStartSequence();
      break;
    case 1:
      findStopSequence();
      break;
    case 2:
      findPowerSequence(); //look for power sequence and extract
      break;
    case 3:
      publishMessage();
      break;
  }
}
void findStartSequence() {
  while (Serial.available())
  {
    inByte = Serial.read();//read serial buffer into array
       if (inByte == startSequence[startIndex])//in case byte in array matches the start sequence at position 0,1,2...
    {
      smlMessage[startIndex] = inByte;//set smlMessage element at position 0,1,2 to inByte value
      startIndex++;
      if (startIndex == sizeof(startSequence))//all start sequence values have been identified
      {
        //   Serial.println("Match found");
        stage = 1;
     
      smlIndex = startIndex;
     
                startIndex = 0;
      }
    }
    else {
      startIndex = 0;
    }
  }
}
void findStopSequence() {
     while (Serial.available())
  {
    inByte = Serial.read();
    smlMessage[smlIndex] = inByte;
    smlIndex++;
    if (inByte == stopSequence[stopIndex])
    {
      stopIndex++;
      if (stopIndex == sizeof(stopSequence))
      {
                stage = 2;
        stopIndex = 0;
        // after the stop sequence, ther are sill 3 bytes to come.
        // One for the amount of fillbytes plus two bytes for calculating CRC.
        for (int c = 0 ; c < 3 ; c++) {
          smlMessage[smlIndex++] = Serial.read();
          if (stopIndex == sizeof(stopSequence))
          {
            stage = 2;
            stopIndex = 0;
            // after the stop sequence passed, there are sill 3 bytes to come.
            // One for the amount of fillbytes plus two bytes for calculating CRC.
            delay(3); // wait for the 3 bytes to be received.
            for (int c = 0 ; c < 3 ; c++) {
              smlMessage[smlIndex++] = Serial.read();
            }
            // smlIndex is at this point one bigger than the amount of stored inBytes because it is incremented evreytime after reading.
            // To store the real smlIndex, we have to substract the last incrementation.
            smlIndex--;
          }

 
      }
      }
    }
    else {
            stopIndex = 0;
    }
  }
}
void findPowerSequence() {
  byte temp; //temp variable to store loop search data
 startIndex = 0; //start at position 0 of exctracted SML message
 
for(int x = 0; x < sizeof(smlMessage); x++){ //for as long there are element in the exctracted SML message
    temp = smlMessage[x]; //set temp variable to 0,1,2 element in extracted SML message
    if (temp == powerSequence[startIndex]) //compare with power sequence
    {
      startIndex++;
      if (startIndex == sizeof(powerSequence)) //in complete sequence is found
      {
        for(int y = 0; y< 4; y++){ //read the next 4 bytes (the actual power value)
          power[y] = smlMessage[x+y+1]; //store into power array
        }
        stage = 3; // go to stage 3
        startIndex = 0;
      }
    }
    else {
            startIndex = 0;
    }
  }
   currentpower = (power[0] << 24 | power[1] << 16 | power[2] << 8 | power[3]); //merge 4 bytes into single variable to calculate power value
}
void publishMessage() {
  //  int arrSize = 2 * smlIndex + 1;
  //  char smlMessageAsString[arrSize];
  //  char *myPtr = &smlMessageAsString[0]; //or just myPtr=charArr; but the former described it better.
  //
  //  for (int i = 0; i < smlIndex; i++) {
  //    snprintf(myPtr, 3, "%02x", smlMessage[i]); //convert a byte to character string, and save 2 characters (+null) to charArr;
  //    myPtr += 2; //increment the pointer by two characters in charArr so that next time the null from the previous go is overwritten.
  //  }
  //Serial.print("Byte count: ");
  //Serial.println(smlIndex);
   //Serial.print('\n');
        //output 4 bytes of exctracted power bytes
//for(int x = 0; x < 4; x++){
//Serial.print(power[x],HEX);
//Serial.print(" ");
//}
      //output calculated "Wirkleistung"
Serial.print("Leistung: ");
Serial.println(currentpower);
//hier wird aus currentpower  dien Wert der nur zwischen 0 und 998
//sein kann , falls größer ist er immer 998
if(currentpower>998)currentpower=998;
//hier wird der int Currentpower in einen byte Wert gewandelt und durch 3,9 geteilt für das Verhältnis
//1000W = 100%, 255=100% entpricht 100/255=0,39 0,39*10 (10W entpricht 1% von 1000W)
byte analogpower = currentpower / 3.9;
Serial.println(analogpower);// gibt den analogwert aus zum Debug
analogWrite(9,analogpower);
int currentpower1 = currentpower;
Serial.print('\n');
      //output 8 bytes of exctracted consumption bytes
for(int x = 0; x < 8; x++){

 }
   
   
  // clear the buffers
  smlIndex = 0;
  memset(smlMessage, 0, sizeof(smlMessage));
  memset(power, 0, sizeof(power));
 
 
 
  stage = 0; // start over
 
}

Go Up