Arduino Mega slimme meter uitlezen met Solarmeter Harold65

Arduino specifieke Software
Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor Koepel » 20 Jun 2019, 18:29

Ik heb het indrukwekkend gemaakt :twisted: :lol:
Door millis() en een Finite State Machine te gebruiken is er tijdens het inlezen nog tijd om iets anders te doen. Als de sketch in de STATE_IDLE zit, dan zouden er internet dingen gedaan kunnen worden. Mijn idee was om een basis te leggen, waarbij de rest van de sketch van Harold daar misschien aan toegevoegd kan worden. Maar dat ga ik niet doen.

De Arduino Leonardo heeft een ongebruikte hardware seriële poort op pin 0 en 1. Die heet "Serial1". Dat is nu eenmaal zo.

Ik probeerde nog een Arduino Uno met SoftwareSerial, maar die kan echt geen 115200 baud inlezen.

Een Arduino gebruiken om enkel en alleen een telegram te vertragen kan natuurlijk ook eenvoudiger. Vooral als ik een beetje kort-door-de-bocht code schrijf.
Dan is nog steeds de Arduino Leonardo/Micro/Pro Micro nodig.
Om onderscheid te maken, heb ik deze een andere naam gegeven: "P1 poort verslomer".

cpp code
// P1 poort verslomer
// ------------------
//
// Board
// -----
// Arduino Leonardo/Micro/Pro Micro of een andere ATmega32U4.
//
// Werking
// -------
// De 115200 8N1 seriele data van de P1 poort wordt ingelezen op pin 0.
// Het wordt vertraagd op 9600 baud verstuurd op pin 9.
//
// Versies
// -------
// Versie 1, 20 juni 2019
// Eerste versie.
// Versie 2, 20 juni 2019
// memset() voor Serial.readBytesUntil() toegevoegd.
//
//

#include <SoftwareSerial.h>

SoftwareSerial portSlow( 8, 9); // RX, TX

#define BUFFER_SIZE 1024

char buffer[BUFFER_SIZE];

void setup()
{
Serial1.begin( 115200); // alleen RX wordt gebruikt
portSlow.begin( 9600); // alleen TX wordt gebruikt
}

void loop()
{
Serial1.setTimeout( 0);
Serial1.readBytes( buffer, BUFFER_SIZE); // de RX buffer van de library leegmaken
Serial1.setTimeout( 15000UL); // 15 seconden timeout
Serial1.find( '/'); // zoek start teken
memset( buffer, '\0', BUFFER_SIZE); // buffer leegmaken, dan is er ook meteen een zero terminator.
Serial1.readBytesUntil( '!', buffer, BUFFER_SIZE); // lees tot einde van telegram

portSlow.println( buffer); // Verstuur langzaam op 9600 baud

delay( 7000); // wacht 7 seconden
}
Laatst gewijzigd door Koepel op 20 Jun 2019, 19:19, in totaal 2 keer gewijzigd.

Advertisement

Gebruikers-avatar
Berichten: 117
Geregistreerd: 10 Jun 2019, 12:16
Woonplaats: Amsterdam

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor master64nl » 20 Jun 2019, 18:57

Ik word hier alleen maar tureluurs van :? :roll:
Maar eh, moet ik zo`n printje bestellen?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor Koepel » 20 Jun 2019, 20:18

master64nl schreef:Ik word hier alleen maar tureluurs van :? :roll:

Maar ik heb de regels code in de loop() gereduceerd tot slechts acht.

Je kunt zo'n printje bestellen, als het eerst werkte, dan moet het mogelijk zijn om het met de Arduino Leonardo/(Pro)Micro ook werkend te krijgen. Desnoods kan in de sketch een aantal overbodige regels er uit gehaald worden.

Als de "P1 poort verslomer" nog niet helemaal werkt, dan is het ook mogelijk om te versturen met 9600 baud met 1ms pauze er tussen.
Mocht de SoftwareSerial toch niet werken, dan kun je terug vallen op de eerste, de "P1 poort vertrager".

Ik heb intussen de CRC ook werkend.

Gebruikers-avatar
Berichten: 117
Geregistreerd: 10 Jun 2019, 12:16
Woonplaats: Amsterdam

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor master64nl » 20 Jun 2019, 20:34

Besteld met promotie code voor 2,79 ;)
Moet ik deze direct op de Mega of Ethernet shield prikken? Of alleen voeding en bepaalde digitale pinnen verbinden met elkaar?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor Koepel » 20 Jun 2019, 21:16

Je kunt de GND pin en de 5V pin met de GND en 5V van de Arduino Mega 2560 verbinden.
De andere pinnen voor RX en TX staan beschreven in de sketch zelf.

Hieronder een derde sketch. Die laat alleen het telegram zien, en berekent de CRC.
Het blijkt dat de crc16 berekening al bij de Arduino er in zit.
Dus alleen dit was nodig:
cpp code
#include <util/crc16.h>

uint16_t crc = 0;
for( int i=0; i<n; i++)
crc = _crc16_update( crc, buffer[i]); // gebruik de standaard crc16


Hieronder de sketch. Ik denk dat het zonder wijzigingen op de Arduino Mega 2560 draait.
Maar je kunt het ook gebruiken om je nieuwe Arduino boardje te testen ;)
cpp code
// P1 poort tester
// ---------------
//
// Board
// -----
// Arduino Leonardo/Micro/Pro Micro of een andere ATmega32U4.
// Deze sketch zou zonder wijzigingen op een Arduino Mega 2560
// kunnen draaien. Dat heb ik nog niet geprobeerd.
//
// Werking
// -------
// De 115200 8N1 seriele data van de P1 poort wordt ingelezen op pin 0
// bij een Leonardo of anders de RX pin van Serial1 bij een Mega 2560.
// Vanzelfsprekend het signaal van de P1 poort inverteren zodat het
// een normaal serieel signaal wordt met idle hoog en startbit laag.
// In de seriele monitor wordt het telegram weergegeven.
// Ze de seriele monitor ook op 115200 baud !
//
// Versies
// -------
// Versie 1, 20 juni 2019
// Eerste versie.
// De CRC berekening werkt, maar testen van verkeerde invoer is niet perfect.
//
// CRC
// ---
// De CRC is een standaard crc16 vanaf het '/' teken tot en met het '!'.
// Inclusief die beide tekens zelf en inclusief alle '\r' en '\n'.
// Na de '!' komt de checksum.
// Dat zijn altijd 4 hexadecimale cijfers, bijvoorbeeld: 0A89
//
//

#include <util/crc16.h>

#define BUFFER_SIZE 1024
byte buffer[BUFFER_SIZE];

unsigned long previousMillis;

unsigned int telegramCount;
unsigned int errorCount;


void setup()
{
Serial.begin( 115200); // Stel de seriele monitor in op 115200 baud.
while( !Serial); // Wacht totdat de seriele monitor geopend is (Leonardo).
Serial.println(F( "==================================================="));
Serial.println( "De sketch \"P1 poort tester\" loopt");
Serial.println(F( "==================================================="));

Serial1.begin( 115200); // Voor de P1 poort, alleen RX wordt gebruikt

// Maak pin 13 hoog, die is misschien verbonden met het RTS signaal.
// Bijvoorbeeld als iemand de "P1 poort vertrager" met pin 13 heeft gebruikt.
pinMode( 13, OUTPUT);
digitalWrite( 13, HIGH);
}


void loop()
{
Serial1.setTimeout( 15000UL); // 15 seconden timeout, een hogere waarde mag ook.
if( Serial1.find( '/')) // zoek het begin van een telegram
{
unsigned long currentMillis = millis(); // onthoudt dit tijdstip
memset( buffer, '\0', BUFFER_SIZE); // maak buffer schoon, en zorg meteen voor zero-terminator
buffer[0] = '/'; // zet de '/' ook nog in de buffer, nodig voor de CRC
Serial1.setTimeout( 2000UL); // 2 seconden timeout om de rest van het telegram in te lezen.
int m = Serial1.readBytesUntil( '!', &buffer[1], BUFFER_SIZE - 2); // lees tot einde-teken van telegram

if( m > 2) // Is er iets ontvangen ? Negeer minder dan 2 bytes
{
telegramCount++; // hou aantal ontvangen telegrammen bij.

// De '!' is gelezen, maar zit nog niet in de buffer.
// De '!' is echter wel nodig bij de crc checksum.
// Na de '!' komen nog 4 cijfers met de checksum, en daarna carriage return en linefeed.

int n = (int) strlen( (char *) buffer);
if( n < BUFFER_SIZE - 2)
{
buffer[n] = '!'; // voeg de '!' alsnog toe aan de buffer
n++;
}

uint16_t crc = 0;
for( int i=0; i<n; i++)
crc = _crc16_update( crc, buffer[i]); // gebruik de standaard crc16

// Lees ook de 4 cijfers van de checksum, en zet die dan meteen om naar een unsigned integer.
unsigned int crcTelegram = 0xFFFF; // zomaar een waarde, de 'crc' is al default 0, dus deze anders.
if( n < BUFFER_SIZE - 5 && Serial1.available() > 4) // is er nog een checksum ?
{
for( int i=0; i<4; i++) // lees de 4 cijfers van de crc
{
buffer[n++] = (byte) Serial1.read();
}
sscanf( (char *) &buffer[n-4], "%4x", &crcTelegram);
}

if( crc != crcTelegram) // test de berekende waarde met de ingelezen checksum
{
errorCount++;
}
}

Serial.println( (char *) buffer); // Druk het gehele telegram af

Serial.println(F( "---------------------------------------------------"));
Serial.print(F( "Aantal telegrammen: "));
Serial.println( telegramCount);
Serial.print(F( "Waarvan foute CRC : "));
Serial.println( errorCount);
Serial.print(F( "Telegram iedere : "));
float t = float(currentMillis - previousMillis) / 1000.0;
Serial.print( t);
Serial.println(F( " seconden"));
Serial.println(F( "---------------------------------------------------"));

previousMillis = currentMillis; // onthouden, de volgende keer wordt verschil berekend.
}
}
Laatst gewijzigd door Koepel op 20 Jun 2019, 21:46, in totaal 3 keer gewijzigd.

Gebruikers-avatar
Berichten: 117
Geregistreerd: 10 Jun 2019, 12:16
Woonplaats: Amsterdam

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor master64nl » 20 Jun 2019, 21:29

Wat betekent CCP en waar staat die?
Hoe en waar zet ik die code?
Is de eerste code voor de Mega of de nieuwe?
Zet ik die nieuwe skets van jou in een map vertrager die weer in de map libaries van Arduino staat?
Begrijp ik het goed dat ik het IC 7404 niet meer nodig heb omdat het al geïnverteerd word?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor Koepel » 20 Jun 2019, 21:40

Natuurlijk heb je jouw inverter (7404 of transistor) nog nodig. Heb ik dat onduidelijk beschreven ?

In de Arduino IDE kies je in het menu bij "Bestand" voor "Nieuw", daar kopieer je mijn sketch naar toe en dan "opslaan als" en dan de naam invullen. Bijvoorbeeld "P1_poort_tester".

Voor welke Arduino board het is, dat staat in de sketch.
Ik heb al dat commentaar bovenaan in de sketch (in het groen) toch niet geschreven om af te drukken en als behang te gebruiken :lol:

Dit forum heeft twee manieren om code te laten zien met "code tags". De ene laat het wat kaal zien, de andere zet er "cpp code" boven. Niet op letten, ik had ook liever dat het er niet stond.
Meestal zet ik mijn muis aan het begin (zonder de regelnummers), en trek ik met mijn muis zodat ik de hele sketch heb, dan Ctrl+C en in de Arduino IDE kopieren. Lukt dat een beetje ? Ik kan ook de sketch als bijlage toevoegen.

Gebruikers-avatar
Berichten: 117
Geregistreerd: 10 Jun 2019, 12:16
Woonplaats: Amsterdam

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor master64nl » 21 Jun 2019, 06:13

Dit stukje heb je apart genoemd:
#include <util/crc16.h>

uint16_t crc = 0;
for( int i=0; i<n; i++)
crc = _crc16_update( crc, buffer[i]); // gebruik de standaard crc16



Ik krijg een foutcode als ik de P1_vertrager controleer:
Pi_vertrager.ino: In function 'void loop()':
Pi_vertrager:65: error: invalid conversion from 'char' to 'char*'
Pi_vertrager:65: error: initializing argument 1 of 'bool Stream::find(char*)'
Pi_vertrager:71: error: invalid conversion from 'byte*' to 'char*'
Pi_vertrager:71: error: initializing argument 2 of 'size_t Stream::readBytesUntil(char, char*, size_t)'

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor Koepel » 21 Jun 2019, 07:53

Dat stukje heb ik apart genoemd om te laten zien hoe weinig nodig is om de checksum te berekenen.
De "checksum" die het telegram gebruikt, is een "CRC" checksum: https://nl.wikipedia.org/wiki/Cyclic_redundancy_check.
En een stardaard CRC checksum is de CRC16, en Arduino heeft daar al een functie voor: _crc16_update()

Ik heb: byte buffer[1024];
in plaats van: char buffer[1024];
en daar zou een foutmelding op kunnen komen.
Maar jij lijkt een hele andere 'Stream' library te hebben.

Ik gebruik "Arduino 1.8.9" en ik selecteer "Arduino Leonardo", toen kreeg ik die foutmeldingen niet.
Do jij iets anders ?
Probeer je om die sketch te compileren voor een ESP8266 ?

Kijk eens bovenin de sketch hoe die heet.
De "P1_vertrager" heeft geen find().
Je bedoelt de "P1 poort verslomer" sketch ?
Laatst gewijzigd door Koepel op 21 Jun 2019, 08:03, in totaal 1 keer gewijzigd.

Gebruikers-avatar
Berichten: 117
Geregistreerd: 10 Jun 2019, 12:16
Woonplaats: Amsterdam

Re: Arduino Mega slimme meter uitlezen met Solarmeter Harold

Berichtdoor master64nl » 21 Jun 2019, 08:02

Koepel schreef:Dat stukje heb ik apart genoemd om te laten zien hoe weinig nodig is om de checksum te berekenen.
De "checksum" die gebruikt wordt is een "CRC" checksum: https://nl.wikipedia.org/wiki/Cyclic_redundancy_check.
En een stardaard CRC checksum is de CRC16, en Arduino heeft daar al een functie voor: _crc16_update()
Dat is mooi dat dit er al in zit :)

Ik heb: byte buffer[1024];
in plaats van: char buffer[1024];
en daar zou een foutmelding op kunnen komen.
Maar jij lijkt een hele andere 'Stream' library te hebben.

Ik gebruik "Arduino 1.8.9" en ik selecteer "Arduino Leonardo", toen kreeg ik die foutmeldingen niet. Ik heb 1.0.5 R2 ofzo. Dat had te maken dat bepaalde dingen niet zichtbaar werden in Soalrmeter 11.43. Heeft iemand weer op het wijhebbenzon forum bedacht. Beschrijving heb ik ergens opgeslagen.
Do jij iets anders ? Ik gebruik 1.0.5 r2
Probeer je om die sketch te compileren voor een ESP8266 ? Nee!

Ik kan niet testen nu, ben aan het werk :)

Kijk eens bovenin de sketch hoe die heet.
De "P1_vertrager" heeft geen find().
Je bedoelt de "P1 poort verslomer" sketch ?


Ik dacht geef het een naampje. Dus het moet echt P1 verslomer heten?

VorigeVolgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 45 gasten