Serial2.available unexpected behaviour

Ik ben bezig om de p1 poort van een slimme meter uit te lezen. Hierbij kom ik wat vreemde dingen tegen bij Serial2.available():
Wanneer ik niets op de serial2 poort heb aangesloten, en in set-up de data voor de seriele poort gewist heb, dan is bij het starten van de loop Serial2.available 1. Ik had 0 verwacht. Wanneer ik daarna Serial2.read uitvoer, geeft deze 0 aan, wat ik verwacht. Lees ik direct daarna de poort nogmaals uit, dan is Serial2. available 0 en Serial2.read -1. Vragen: Waarom is Serial2.available() 1 direct na opstarten? Waarom wordt Serial2.read -1 in de tweede ronde?
Ik gebruik de Arduino Due als platform.
Met vriendelijke groet, Gerard


/*********************************************************************************************/
/*                                                                                           */
/*                        Serial.available test                                              */
/*********************************************************************************************/
// Libraries
#include <SPI.h>

//=================================
//tijd en timer variabelen
//=================================
unsigned long tijd          = 0;
unsigned long millisprev    = 0;
unsigned long milliseconds  = 0;      // milliseconden variable in milliseconden
unsigned long seconds       = 0;      // seconden variable in milliseconden
unsigned long tijdp1        = 0;      // tijd variabele
unsigned long tijdKlok      = 0;


//=================================
// watchdog variabelen
//=================================

int watchdogTime      = 16000;   // Definieert de tijd voor de watchdog in ms, maximum tijd is 16 sec.


//====================================================================
//=========================SET-UP=====================================
//====================================================================
void setup(){
  watchdogEnable(watchdogTime);

//==================================================================
// serial port setup
//==================================================================
Serial.begin(115200);                         // monitoring via seriele poort

Serial2.begin(115200, SERIAL_7E1);            // serial port 2 voor P1 poort Landis E350(ZCF100, DSM versie 4.2) meter

  while(Serial2.available()){
  Serial2.read();                             // this flushes the serial2 input
  }
  Serial.println("Hello World");
  

//===================================================================
// tijdklok starten
//===================================================================
  tijdklok();   
  tijdp1        = tijdKlok;      
 }

//===================================================================
//=========================Start Loop================================
//===================================================================
void loop() {
  tijdklok(); 
  
  if (tijdp1 < tijdKlok) {   // tijdstip wanneer de seriele poort gecheckt wordt
  tijdp1 = tijdKlok +1 ;     // tijdp1 op tijdKlok plus 1 seconden
  Serial.print("Serial2.available status:    ");
  Serial.println(Serial2.available());
  Serial.print("Serial2.read status:         ");
  Serial.println(Serial2.read());
  Serial.println("");
  watchdogReset();    // reset watchdog
  }
}
    
//============================Subroutines=====================================================
void watchdogSetup(void)  //deze functie is benodigd voor het gebruik van de watchdog
{
}

void tijdklok(){    // == Subroutine tijdklok en timers ====================================================
  tijd = millis() - millisprev;
  milliseconds= milliseconds + tijd;
  seconds = seconds + tijd;
  millisprev = millis();
  tijdKlok = millis()/1000;
}

read() geeft -1 als er niks te lezen is; dus als available() 0 geeft.

Ik zal later proberen naar de rest van he programma te kijken.

1 Like

Dit is de typische output die ik krijg nadat ik de watchdog gerelateerde zaken verwijderd had (programma compileerde niet).

18:25:33.393 -> Hello World
18:25:34.405 -> Serial2.available status:    0
18:25:34.405 -> Serial2.read status:         -1
18:25:34.405 -> 

Het is mogelijk dat RX2 wat oppikt uit de lucht. Je zou voor nu RX2 aan 5V kunnen hangen.

Even een waarschuwing :wink: tijdklok en tijdKlok verschillen maar in een (1) letter; het is heel erg gemakkelijk om daar een fout in te maken.

Vraagje: zegt Hoofddorp en Heerde je wat?

Hoi Sterretje,
Dank voor je snelle reactie!
De watchdog werkt alleen op het Due board, voor een ander platform moet dat er idd uit.
Bijgaand het deel van het gebruikte schema voor de interface voor de P1 poort - seriele ingang. De P1 is een opencollector uitgang met geinverteerde data. Daarom zit daar een pull-up weerstand. Dat heeft wel tot gevolg dat RX2 op nul ligt als er niets aangesloten is. Ziet de poort dat als data als er voor de rest niets gebeurt?
Heerde en Hoofddorp zeggen me zeker iets! Ben benieuwd...

Hi Gerard

Een periode met alleen logische 0 is een break karakter (uart break detection - Google Search) en zolang je je meter niet hebt aangesloten heb je er een hele hoop. Ik heb geen idee hoe de low level seriele ontvangst communicatie daar mee om gaat.

Ik ben verre van een goed electronische ingenieur maar kan in het algemeen schemas volgen :wink: Waarom R31?

Groetjes WimS

Hoi W, Zo is de wereld weer klein...
Ik zal voor de P1 detectie dan de Serial2.read gebruiken, check dat Serial2.read < 1). Dat werkt. En als de P1 aansluiting er wel is, gebruik ik dan Serial2.available().
R31 zit in de emitter. Een kleine weerstand hier zie aan de basis terug met een factor hFe groter, de stroomversterking (rond de 300 ~ 500). Daarmee vormt de schakeling een zeer kleine belasting op de P1 poort.
Groetjes!

Ik heb geprobeerd de specificatie van de P1 connector te vinden. Met wat ik gevonden heb

pin functie
1 5V uit
2 Request in
3 DGND
4 niet gebruikt
5 data uit
6 PGND

Bron: bv. Technical information | Connected Digital Energy Meter en https://www.netbeheernederland.nl/_upload/Files/Slimme_meter_15_a727fce1f1.pdf

In je schema is pin 4 aangesloten. Waarom? Is er een andere specificatie?

Met betrekking to R31. In de digitale electronica wil je een signaal zo hard mogelijk omlaag trekken. Door R31 toe tevoegen gaat het signaal op de collector omhoog met de spanningsval over R31. Nu is die spanningsval wel klein en zal waarshijnlijk geen invloed habben op de detectie van hoog en laag (de spec voor de processor in de Due zegt VIL < 0.3*V<sub>CC</sub>, dus ruw weg 1 V).

De data uitgang van de meter is de open collector van een optocoupler; ik kwam ergens tegen dat de maximale stroom 30 mA. Je zit daar ruim onder voor zover ik kan zien met R37 (4k7).

Ik vermoed dat je pin 6 gaat gebruiken om te bepalen of de meter aangesloten is of niet. Als je meter aangesloten is, is het knooppunt van R35 en R34 0V en zal de Due een laag nivo zien; als de meter niet is aangesloten zal de Due een hoog nivo zien. Als pin 6 inderdaad voor de detectie gebruikt gaat worden hoef je allerlei vreemde constructies te genruiken in je programma met betrekking tot Serial2.available() en Serial2.read() en kunje je beperken tot Serial2.available()

In een simpel voorbeeld

if(digitalRead(9) == LOW
{
  if(Serial2.available())
  {
    // read the data
  }
}
else
{
  // clear received data
  ...

  // flush
  while(Serial2.available())
  {
    // flush the Serial buffer
    ...
  }
}

De else zou moeten voorkomen dat, als de meter los getrokken wordt:

  1. Een half bericht in jouw data buffer zit.
  2. Enige ontvangen data die je nog niet gelezen had verwijdered wordt van de onderliggende buffer.

Op deze manier wordt er weer met een schone lei begonnen als de meter weer wordt aangesloten.

Met betrekking tot Serial2.available() en Serial2.read() kun je de eerste gebruiken om uit te vinden hoeveel ontvangen bytes er in de onderliggende buffer zitten; in simpele termen geeft Serial2.available() het verschil tussen de positie van het eerste ontvangen byte in de onderliggende buffer en de positie waar het volgende ontvangen byte zal worden opgeslagen in de onderliggende buffer .

Met betrekking tot je programma in de opening post:

  1. Waarom gebruik je 7E1 en niet 8N1? De specificties hierboven geven dat laatste aan.
  2. Ik weet niet of je de test gedaan had met je circuit aangesloten of niet, indien met aangesloten circuit zou ik de test herhalen zonder aangeloten circuit om er zeker van te zijn dat het geen programma of Due probleem is.

Als je hulp nodig hebt bij het programmeren van de ontvangst routine, stuur maar een prive bericht hier op het forum. Ik heb geen P1 meter dus het zal een beetje behelpen worden (ik kan altijd proberen er een te simuleren).

Hoi W, De 6P6C plug pin 4 en 6 wordt gebruikt, wanneer ik ipv een P1 meter, een ouderwetse gasmeter met pulse teller wil monitoren. Daarmee ga ik dus geen P1 plug detecteren. Ik heb de laatste code nu een dag of wat draaien en lijkt stabiel. Ik had nog een ander probleem, waarbij mijn klok haywire ging, maar dat gisteren gefikst (blijkbaar mag je geen waarde bij millis() optellen, maar moet je altijd aftrekken). Is je mail adres nog steeds hetzelfde? Dan kan ik je eea sturen. Misschien voor alle zekerheid je mail nog een keer in de prive chat.
Vwb de baudrate, tijdens de installaties kom ik vele typen P1 meters met verschillende baudrates en instellingen. http://domoticx.com/p1-poort-slimme-meter-hardware/
In de originele code wordt de instelling bepaald aan de hand van het type meter wat aangesloten wordt.
Groet, G.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.