Hallo Zusammen,
ich habe es geschafft mit dem Lesekopf von Volkszähler.org meinen EMH EHZ Zähler auszulesen. Leider schaffe ich es nicht die Zahlen zu formatieren, die Ausgabe ist im Moment wie folgt:
10693877
3928
sollte aber 1069.3877 kWh und 392.8W sein. Wenn jemand mehr Ahnung hat als ich, wäre ich auch für eine effizientere Umwandlung von Hex nach INT bzw. Float dankbar.
Vielen Dank im voraus!
Gruss
Norbert
/**
* Copyright (c) 2012 Volker Wegert <ehzy@volker-wegert.de>
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Volker Wegert - initial implementation
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <avr/pgmspace.h>
/***************************************************************************************************
* CONSTANTS
***************************************************************************************************/
/**
* size of the SML message buffer = meximum number of bytes that can be received
*/
#define SML_MSG_BUFFER_SIZE 500
/**
* maximum time to wait for the end of a data packet received via IR
*/
#define SERIAL_READ_TIMEOUT_MS 100
/***************************************************************************************************
* MESSAGES
***************************************************************************************************/
/**
* maximum length of a message (entire text after variable substitution!)
*/
#define MAX_MESSAGE_LENGTH 50
/**
* message numbers
*/
#define MSG_PROGRAM_STOPPED 0
#define MSG_NEXT_FILENAME 1
#define MSG_NO_FILE_NAMES_LEFT 2
#define MSG_INIT_HARDWARE 3
#define MSG_INIT_SD_CARD 4
#define MSG_INIT_SD_CARD_ERROR 5
#define MSG_BYTE_READ 6
#define MSG_BUFFER_OVERFLOW 7
#define MSG_SERIAL_OVERFLOW 8
#define MSG_INVALID_HEADER 9
#define MSG_FILE_OPEN_FAILED 10
#define MSG_FILE_WRITTEN 11
#define MSG_FREE_MEMORY 12
#define MSG_NUM_BYTES_READ 13
/**
* actual message texts - caution, adapt MAX_MESSAGE_LENGTH if required!
* ....+....1....+....2....+....3....+....4....+....5
*/
prog_char msgText00[] PROGMEM = "Program stopped.";
prog_char msgText01[] PROGMEM = "Next output file name is '%s'";
prog_char msgText02[] PROGMEM = "No more file names left";
prog_char msgText03[] PROGMEM = "Initializing Hardware...";
prog_char msgText04[] PROGMEM = "Initializing SD Card...";
prog_char msgText05[] PROGMEM = "SD Card initialization failed";
prog_char msgText06[] PROGMEM = "Read byte %02hhu from IR receiver";
prog_char msgText07[] PROGMEM = "Message buffer overflow";
prog_char msgText08[] PROGMEM = "Serial buffer overflow";
prog_char msgText09[] PROGMEM = "Invalid escape sequence";
prog_char msgText10[] PROGMEM = "Unable to open output file";
prog_char msgText11[] PROGMEM = "%u bytes of data written to file '%s'";
prog_char msgText12[] PROGMEM = "%u bytes of memory available";
prog_char msgText13[] PROGMEM = "%u bytes read";
/**
* table for easier access to the message texts
*/
PROGMEM const char *msgTextTable[] = {
msgText00,
msgText01,
msgText02,
msgText03,
msgText04,
msgText05,
msgText06,
msgText07,
msgText08,
msgText09,
msgText10,
msgText11,
msgText12,
msgText13
};
/***************************************************************************************************
* GLOBAL VARIABLES (YUCK!)
***************************************************************************************************/
/**
* the global buffer to store the SML message currently being read
*/
unsigned char buffer[SML_MSG_BUFFER_SIZE];
unsigned char Aktuell[4];
float aktuell;
/***************************************************************************************************
* SUBROUTINES
***************************************************************************************************/
/**
* printMessage - reads a message text from the PROGMEM, performs variable substitution and
* writes the resulting text to the serial console. Use MSG_* constants for
* messageNumber.
*/
void printMessage(int messageNumber, ...) {
va_list args;
char format[MAX_MESSAGE_LENGTH];
char buffer[MAX_MESSAGE_LENGTH];
va_start(args, messageNumber);
strncpy_P(format, (char*)pgm_read_word(&(msgTextTable[messageNumber])), MAX_MESSAGE_LENGTH);
vsnprintf(buffer, MAX_MESSAGE_LENGTH, format, args);
Serial.println(buffer);
va_end(args);
}
void PrintHex8(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
char tmp[16];
for (int i=0; i<length; i++) {
sprintf(tmp, "0x%.2X",data[i]);
Serial.print(tmp);
Serial.print(" ");
}
}
/**
* stop - stops program execution in a controlled fashion (endless loop).
*/
void stop() {
printMessage(MSG_PROGRAM_STOPPED);
while(1);
}
/**
* isValidHeader - returns true if the global message buffer begins with a valid SML escape sequence.
*/
inline boolean isValidHeader() {
return ((buffer[0] == 0x1b) ||
(buffer[1] == 0x1b) ||
(buffer[2] == 0x1b) ||
(buffer[3] == 0x1b) ||
(buffer[4] == 0x01) ||
(buffer[5] == 0x01) ||
(buffer[6] == 0x01) ||
(buffer[7] == 0x01));
}
/***************************************************************************************************
* MAIN ROUTINES
***************************************************************************************************/
/**
* setup - initialization routine run once after the device is powered up.
*/
void setup() {
// set the serial console speed
Serial.begin(9600);
// set the pin configuration
printMessage(MSG_INIT_HARDWARE);
}
/**
* loop - main program, run in an endless loop
*/
void loop() {
unsigned int nextBufferPosition = 0;
unsigned long lastReadTime = 0;
// clear the message buffer
memset(buffer, 0, sizeof(buffer));
// wait until actual data is available
while (!Serial.available());
// keep reading data until either the message buffer is filled or no more data was
// received for SERIAL_READ_TIMEOUT_MS ms
lastReadTime = millis();
while (millis() - lastReadTime < SERIAL_READ_TIMEOUT_MS) {
if (Serial.available()) {
buffer[nextBufferPosition] = Serial.read();
lastReadTime = millis();
if (nextBufferPosition >= SML_MSG_BUFFER_SIZE) {
printMessage(MSG_BUFFER_OVERFLOW);
return;
}
nextBufferPosition += 1;
}
}
// check the header
printMessage(MSG_NUM_BYTES_READ, nextBufferPosition + 1);
if (!isValidHeader()) {
// not a valid header - notify the user...
printMessage(MSG_INVALID_HEADER);
// ...and empty the receiver buffer (wait for the end of the current data stream
while (Serial.available() > 0) {
Serial.read();
}
}
else {
unsigned char Stand[4];
//PrintHex8(buffer,313);
Serial.println();
for(int i=0;i<4;i++){
Stand[i]=(buffer[143+i]);
Aktuell[i]=buffer[205+i];
}
PrintHex8(Stand,4);
Serial.println();
unsigned long stand =(int(buffer[144])*65536);
unsigned long stand2=(int(buffer[145])*256);
unsigned long stand3=(int(buffer[146]));
unsigned long summe=stand+stand2+stand3;
Serial.println(summe);
unsigned long Verb =(int(Aktuell[1])*65536);
unsigned long Verb2=(int(Aktuell[2])*256);
unsigned long Verb3=(int(Aktuell[3]));
unsigned long verbrauch=Verb+Verb2+Verb3;
Serial.println(verbrauch);
// Serial.println(stand);
// aktuell=*((float*)Aktuell);
// Serial.println(aktuell,DEC);
// for(int i=0;i<4;i++){
// Serial.print(buffer[143+i],HEX);
// }
// Serial.println();
// for(int i=0;i<5;i++){
// Serial.print(buffer[205+i],HEX);
// }
// Serial.println();
// PrintHex8(Aktuell,4);
// Serial.println();
}
}