Einlesen von schnellen HIGH/LOW Signalabfolgen

Hallo zusammen,

ich möchte gerne über meinen Arduino Uno einige Daten eines Fremddevices einlesen. bei diesem Device handelt es sich um einen Chloriantor (CHL) für unseren kleinen Gartepool.

Der CHL verfügt über eine Haupt-PCB und einer Ein- bzw. Ausgabe PCB. die Versorgung zwischen den beiden PCBs wird über 5V sichergestellt. Zur Kommunikation zwischen den PCBs werden HIGH/LOW-Signale verwendet. Diese sehen z.B. so aus, wie im Anhang dargestellt.

Setz man jetzt für die langen Impulse eine 1 und für die kurzen eine 0, so ergibt sich:
1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,0 oder 0xFB04.

Die Daten sind immer 16Bit lang. Es gibt eine Leitung zum Senden, eine zum Empfangen.

Die langen Impulse sind ca. 800us die kurzen 200us lang.

Wenn keine Nachricht empfangen/gesendet wird, liegt HIGH an.

Ich möchte jetzt die Nachrichten belauschen, bzw. eigene Nachrichten senden.

Könnt ihr mir helfen, wie ich am besten vorgehe? Vor allem für das "lauschen" habe ich noch keinen Ansatz.
Später soll es dann auf einem ESP8266 laufen.

Danke für eure Hilfe...

Wenn während der Datenübertragung sonst nicht viel zu tun ist, dann sollte pulseIn() ausreichen.

Für höhere Ansprüche eignet sich der "input capture mode" eines Timers, aber das dürfte mit einem ESP nicht bzw. ziemlich anders laufen. Als Mittelweg ein Ableger der IRremote Bibliothek, die Impulsfolgen in einem 50µs Raster einlesen kann.

Danke schon mal, werde ich testen und berichten

Ich habe da mal was zusammengeschrieben:

für den Sender habe ich einen Arduino Uno verwendet

const int pinOut = 8;
const int bits = 16;
int msgtwo [bits] = {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1};
int msgone [bits] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
int i;
int lang = 795;
int kurz = 195;

void setup() {

  pinMode(pinOut, OUTPUT);
  pinMode(pinIn, INPUT);
}

void loop() {

  digitalWrite(pinOut, HIGH);
  fsk(msgone);
  delay(500);
  fsk(msgtwo);
  delay(500);
}

void fsk (int msg[])
{
  for (i = 0; i < bits; i++) {
    if (msg[i] == 0) {
      digitalWrite(pinOut, LOW);
      delayMicroseconds(kurz);
      digitalWrite(pinOut, HIGH);
      delayMicroseconds(kurz);
    }
    else {
      digitalWrite(pinOut, LOW);
      delayMicroseconds(kurz);
      digitalWrite(pinOut, HIGH);
      delayMicroseconds(lang);
    }
  }
  digitalWrite(pinOut, LOW);
  delayMicroseconds(kurz);
  digitalWrite(pinOut, HIGH);
}

Der Empfänger ist ein ESP8266

const int msglength = 16;
int msg [msglength];
int msgold [msglength];
int eingang = 2;
int i = 0;
unsigned long duration;
const int kurz = 250;
const int lang = 900;
bool anfang = false;

void setup() {

  Serial.begin(115200);
  pinMode(eingang, INPUT);

}

void loop() {




  duration = pulseIn(eingang, HIGH);

  if (duration > lang || duration == 0)
  {
    anfang = true;
  }



  if (anfang == true && digitalRead(eingang) == LOW)
  {
    i = 0;
    while (i < msglength)
    {
      duration = pulseIn(eingang, HIGH);
      if (duration < kurz) msg[i] = 0;
      else if (duration < lang) msg[i] = 1;
      i++;
    }
    anfang = false;
  }

  if (memcmp (msg, msgold, sizeof(msg)) != 0)
  {
    for (i = 0; i < msglength; i++)
    {
      Serial.print(msg[i]);
      Serial.print(",");
      msgold[i] = msg[i];

    }
    Serial.println("");
  }

}

Der Austausch funktioniert auch soweit, nur werden nicht immer alle Daten über Serial.print ausgegeben.
zwischendurch wird z.B. 2mal hintereinander die msg1 empfangen bzw. ausgegeben.
Dies leigt vermutlich am Empfänger, da er noch nicht bereit ist, bzw. anfang noch nicht auf true gesetzt hat, oder?

Über die erste if Abfrage im Empfänger versuche ich den "Anfang" der Nachricht zu finden.

Habt ihr Verbesserungsvorschläge?

mixxer:
Ich habe da mal was zusammengeschrieben:

int i = 0;

if (anfang == true && digitalRead(eingang) == LOW)
 {
   i = 0;
   while (i < msglength)

if (memcmp (msg, msgold, sizeof(msg)) != 0)
 {
   for (i = 0; i < msglength; i++)

Kann man machen, aber las das den Compiler entscheiden.

int i = 0;

  if (anfang == true && digitalRead(eingang) == LOW)
  {
    int i = 0;

  if (memcmp (msg, msgold, sizeof(msg)) != 0)
  {
    for (int i = 0; i < msglength; i++)

mixxer:
Dies leigt vermutlich am Empfänger, da er noch nicht bereit ist, bzw. anfang noch nicht auf true gesetzt hat, oder?

Mit einem Nano als Sender und einem Mega2560 als Empfänger kann ich keinerlei Fehler bei der Übertragung feststellen:

</sup> <sup>0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 5555 1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1, FB05</sup> <sup>

Es könnte also irgendwie mit dem ESP8266 zusammenhängen, der beispielsweise keine 5 V verträgt. Mangels ESP8266 kann ich das aber nicht testen.

Danke euch.
Ich werde es heute Abend nochmal testen.