VLC mit LED und Photodiode. Frage zu Receiver code!!

Sehr geehrte Damen und Herren,

ich bin leider noch ziemlich neu im Bereich Visible Light Communication sowie Arduino. Also, bitte verzeiht mir, falls ich mal was nicht verstehe.

So nun zum Thema : Ich habe sowohl die Transmitterschaltung als auch die Receiverschaltung vollständig. Sie kommunizieren auch miteinander. Des Weiteren habe ich den Transmittercode fertig.(Siehe Anhang)

#include <avr/io.h>
#include <TimerOne.h> 

#define ON (PORTB=B00100000)
#define OFF  (PORTB=B00000000)
volatile int counter = 0;
volatile int timer1;
int i,box[8];
char moji='a';
char m;
unsigned char temp;

void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  Timer1.attachInterrupt(timerIsr);  //関数の名前、TimerⅠを用いる//
  Timer1.initialize(50); //25us毎に動く//
 

}

void timerIsr(){
  counter++;
}

void loop(){
   counter = 0;
   timer1 = 0;
   for(i=0;i<16;i++){
     OFF;
      timer1 = timer1 + 6;   //delayのかわり// //timer1+6:50*6=300u//
  while(counter <= timer1){
  }
  ON;
  timer1  = timer1 + 2;
  while(counter <= timer1){
  }
  
   m=moji;
  for(i=0;i<8;i++){
  temp=m&128;   
  if(temp==0){
    send0();
    box[i]=0;
  }else if(temp==128){
    send1();
    box[i]=1;
  }
    m=m<<1;
    }
    
  OFF;
  timer1  = timer1 + 2;
  while(counter <= timer1){
    }
  }
}

void send0(){
   OFF;
  timer1  = timer1 + 2;
  while(counter <= timer1){
  }
   ON;
      timer1 = timer1 + 2;   
  while(counter <= timer1){
  }
}


void send1(){
  ON;
      timer1 = timer1 + 2;   
  while(counter <= timer1){
  }
   OFF;
  timer1  = timer1 + 2;
  while(counter <= timer1){
  }
}

Jedoch weiß ich einfach nicht, wie ich den Receivercode schreiben kann. Ich habe zwar angefangen jedoch, glaube ich , dass ich total daneben liege.

volatile int counter1;
volatile int counter2;
int i,box[16],receive;
unsigned char Threshold = 500;
unsigned long time;


void setup() {
Serial.begin(9600);
pinMode(13,INPUT);
digitalWrite(13,HIGH);
for(i=o;i<16;i++)


}

void loop() {
  Serial.print("Time:")
  time = millis();
  //print time since program started
  if(receive<Threshold = counter1+1){
    else(receive>Threshold =counter2+1
  }
}

Die Idee ist ein Threshold von 500. Falls ein Eingang von mehr als 500 registriert wird, sollte counter2+1 gerechnet werden und bei weniger als 500 counter1+1. Am Ende des Programms soll counter1 und counter 2 miteinander verrechnet werden, so dass, wenn counter1 überwiegt eine 1 als outcome dargestellt wird und bei counter2 eine 0.

Ich hoffe, ich konnte mein Problem einfach darstellen. Jede Hilfe ist Willkommen. Falls etwas unklar sein sollte bitte bescheid geben.

Vielen Danke!

Ich weiß nicht, wo ich da anfangen soll. Wo kommen denn die vielen chinesischen Zeichen her, stammst Du aus dieser Gegend?

Erst mal zur Elektronik: das empfangene Signal (blau?) fällt IMO viel zu langsam ab, zeige doch mal das Schaltbild. Da könnte ein kleinerer oder größerer Lastwiderstand hilfreich sein. Das Abtasten mit analogRead() dürfte viel zu langsam sein, ein Threshold müßte daher in Hardware realisiert werden. Ggf. kann auch der interne Komparator verwendet werden, aber normalerweise sollte ein brauchbares Signal einfach mit digitalRead() abgefragt werden.

Die Erzeugung des Signals würde ich in die ISR des Timers verlegen. Der bekommt das auszugebende Byte übergeben, und stellt dann fest, nach wievielen Takten das Ausgangssignal umgeschaltet werden soll. Oder er bekommt ein Array, in dem die High und Low Zeiten (Takte) enthalten sind. So wird das Timing viel stabiler, als wenn in loop() ggf. noch andere Arbeiten anfallen. Stichwort “non-blocking” (nicht-blockierender) Code.

Beim Zugriff auf volatile Variablen mit mehreren Bytes müssen die Interrupts beim Zugriff aus dem Hauptprogramm abgeschaltet werden, sonst könnte ein Interrupt zwischen dem Lesen oder Schreiben der einzenen Bytes den Wert verfälschen. Wenn die zu übergebenden Werte nur einzelne Bytes (byte/bool/char) sind, kann man sie direkt (atomar) lesen und schreiben, da können keine Interrupts dazwischenspucken.

Ähnlich beim Empfänger, da zählt die ISR die Takte des High und Low Eingangssignals, und kann diese Zeiten in Bits umrechnen und daraus die empfangenen Bytes machen. Das Hauptprogramm bekommt dann nur ein Flag, wann ein Byte vollständig empfangen wurde.

Kannst du evtl. noch einmal kurz erklären, was du mit deinem Sketch erreichen möchtest ?

Und auch welche Bauteile du verwendest ?

Auch ist interessant, warum du einen IRQ dafür einsetzen willst.

Ist es nicht einfachr die IR Bibliothek zu verwenden?

Grüße Uwe

Der Sender in der IR Bibliothek erzeugt die modulierte Trägerfrequenz, funktioniert also nur mit einem entsprechenden Empfänger-Modul. Das ist aber nicht wirklich ein Nachteil, durch Verwendung der Trägerfrequenz wird ja die Störsicherheit gegen Fremdlicht erreicht.

Hallo,

Vielen Dank für die Rückmeldungen.

DrDiettrich:
Ich weiß nicht, wo ich da anfangen soll. Wo kommen denn die vielen chinesischen Zeichen her, stammst Du aus dieser Gegend?

Erst mal zur Elektronik: das empfangene Signal (blau?) fällt IMO viel zu langsam ab, zeige doch mal das Schaltbild. Da könnte ein kleinerer oder größerer Lastwiderstand hilfreich sein. Das Abtasten mit analogRead() dürfte viel zu langsam sein, ein Threshold müßte daher in Hardware realisiert werden. Ggf. kann auch der interne Komparator verwendet werden, aber normalerweise sollte ein brauchbares Signal einfach mit digitalRead() abgefragt werden.

Ich habe nun versucht meine Schaltung per EAGLE zu zeichnen. ich hoffe Ihr könnt es verstehen. Ich habe sicherheitshalber noch Bilder von meiner Schaltung gemacht, welche sich im Anhang befinden. Ich befinde mich zur Zeit in Japan deshalb die japanischen Zeichen.

DrDiettrich:
Die Erzeugung des Signals würde ich in die ISR des Timers verlegen. Der bekommt das auszugebende Byte übergeben, und stellt dann fest, nach wievielen Takten das Ausgangssignal umgeschaltet werden soll. Oder er bekommt ein Array, in dem die High und Low Zeiten (Takte) enthalten sind. So wird das Timing viel stabiler, als wenn in loop() ggf. noch andere Arbeiten anfallen. Stichwort “non-blocking” (nicht-blockierender) Code.

Beim Zugriff auf volatile Variablen mit mehreren Bytes müssen die Interrupts beim Zugriff aus dem Hauptprogramm abgeschaltet werden, sonst könnte ein Interrupt zwischen dem Lesen oder Schreiben der einzenen Bytes den Wert verfälschen. Wenn die zu übergebenden Werte nur einzelne Bytes (byte/bool/char) sind, kann man sie direkt (atomar) lesen und schreiben, da können keine Interrupts dazwischenspucken.

Ähnlich beim Empfänger, da zählt die ISR die Takte des High und Low Eingangssignals, und kann diese Zeiten in Bits umrechnen und daraus die empfangenen Bytes machen. Das Hauptprogramm bekommt dann nur ein Flag, wann ein Byte vollständig empfangen wurde.

Ich denke ich habe es teilweise verstanden, bin mir aber nicht sicher wie ich es umsetzen soll. Könntest du es bitte für “Dummies” erklären bitte? Vielen Dank!

HotSystems:
Kannst du evtl. noch einmal kurz erklären, was du mit deinem Sketch erreichen möchtest ?

Und auch welche Bauteile du verwendest ?

Auch ist interessant, warum du einen IRQ dafür einsetzen willst.

Es soll einfach bytes gesendet und empfangen werden.

Nochmal Vielen dank für die Rückmeldungen. Leider müsst Ihr mir manche sachen genauer erklären, da es das erste mal in diesem Bereich arbeite.

Vielen Dank!

NJM386BD.pdf (239 KB)

Du schreibst leider nicht, was du damit erreichen möchtest.
Deine Angaben sind nicht sehr aussagekräftig.

Und was soll der Kondensator in der Leitung zur IR-Diode ?
Was willst du mit dem Audioverstärker anfangen ?

Hoffentlich enthält Dein Aufbau nicht so viele Fehler wie die Schaltungsbildchen. Einfache Schaltpläne wären einfacher zu verstehen, mit Verbindungslinien die den Fluß der Signale wiedergeben, und nicht als Vogelschau auf irgendwelche IC mit irgendwie angeordneten Pins. Schau Dir mal “richtige” Schaltpläne an, mit Versorgung oben und Masse unten, und Signale die von links nach rechts weitergegeben werden.

Wenn Du mit der Programmierung noch so weit am Anfang stehst, dann kann es hilfreich sein, erst einmal fremde Programme zu studieren, wie dort mit der Ablaufsteuerung, Interrupts, volatilen Variablen etc. umgegangen wird.

So wie das in deinem Schaltplan für den Receiver dargestellt ist
hast du A0 über einen Kondensator entkoppelt mit GND verbunden.
Sonderlich viel bringt dir das nicht.

Der Kondensator muss zwischen die Photodiode und dem Wiederstand und mit GND.
A0 muss ebenfalls zwischen Photodiode und Wiederstand.

Aber nicht entkoppelt über den Kondensator.

HotSystems:
Du schreibst leider nicht, was du damit erreichen möchtest.
Deine Angaben sind nicht sehr aussagekräftig.

Und was soll der Kondensator in der Leitung zur IR-Diode ?
Was willst du mit dem Audioverstärker anfangen ?

Also ich muss in einem Büro mit LED-Streifen eine Licht Infrastruktur aufbauen, welche eine Geschwindigkeit von bis zu 1Mbps erzeugt. Ich habe als Receiver eine Photodiode ausgewählt. Natürlich sollte es kein Flickern geben und das Büro sollte hell beleuchtet werden mit den LED-Streifen. Im besten Falle sollte die Kommunikation bis zu 2 Meter gehen.

Den Kondensator haben die Leute im Labor mir vorgeschlagen. Den Audioverstärker haben sie mir gegeben, damit ich die 12 V für die LED-Streifen erreichen kann, da der Nano nur 5 V bereitstellen kann. Werden beide Komponenten nicht benötigt?

Addi2438:
So wie das in deinem Schaltplan für den Receiver dargestellt ist
hast du A0 über einen Kondensator entkoppelt mit GND verbunden.
Sonderlich viel bringt dir das nicht.

Der Kondensator muss zwischen die Photodiode und dem Wiederstand und mit GND.
A0 muss ebenfalls zwischen Photodiode und Wiederstand.

Aber nicht entkoppelt über den Kondensator.

ich werde es korrigieren. Danke! aber mein großes problem ist das Programmieren. ich werde dann das neue hoffentlich richtige Schaltplan hochladen.

DrDiettrich:
Hoffentlich enthält Dein Aufbau nicht so viele Fehler wie die Schaltungsbildchen. Einfache Schaltpläne wären einfacher zu verstehen, mit Verbindungslinien die den Fluß der Signale wiedergeben, und nicht als Vogelschau auf irgendwelche IC mit irgendwie angeordneten Pins. Schau Dir mal "richtige" Schaltpläne an, mit Versorgung oben und Masse unten, und Signale die von links nach rechts weitergegeben werden.

Wenn Du mit der Programmierung noch so weit am Anfang stehst, dann kann es hilfreich sein, erst einmal fremde Programme zu studieren, wie dort mit der Ablaufsteuerung, Interrupts, volatilen Variablen etc. umgegangen wird.

ich werde mir mal so einen "richtigen" Schaltplan angucken und meinen aktualisieren. Ich habe mir viele Programme angeguckt, jedoch sind alle voneinander total unterschiedlich oder ich weiß einfach nicht was ich zu googeln habe.

Den Kondensator am Empfänder solltest du evtl sogar ganz weglassen.
Ansonsten hast du keine digitalen Signale mehr.

Außer du willst explizit z.B. ein moduliertes Signal glätten.

Da bekommst du dann ein analoges Signal raus.

Wenn du sowas vor hast wäre ein Bandpass allerdings besser.

Edit:

Warum besorgst du dir eigentlich nicht gleich einen fertigen IR-Empfänger?

Da brauchst du dir um son Zeug keine Gedanken machen.

Wozu brauchst Du denn die hohe Datenrate? Willst Du Bilder anzeigen, oder was?

Die 12V sind mir auch nicht klar. Als Versorgung brauchen die Streifen mehr als was ein Verstärker ausgeben kann, und die Steuerung erfolgt normalerweise mit Logikpegel (3-5V).

Addi2438:
Den Kondensator am Empfänder solltest du evtl sogar ganz weglassen.
Ansonsten hast du keine digitalen Signale mehr.

Außer du willst explizit z.B. ein moduliertes Signal glätten.

Da bekommst du dann ein analoges Signal raus.

Wenn du sowas vor hast wäre ein Bandpass allerdings besser.

Edit:

Warum besorgst du dir eigentlich nicht gleich einen fertigen IR-Empfänger?

Da brauchst du dir um son Zeug keine Gedanken machen.

Ich möchte ein digitalen Signal. Ich versuche es mal mit dem IR-Empfänger. Danke!

DrDiettrich:
Wozu brauchst Du denn die hohe Datenrate? Willst Du Bilder anzeigen, oder was?

Die 12V sind mir auch nicht klar. Als Versorgung brauchen die Streifen mehr als was ein Verstärker ausgeben kann, und die Steuerung erfolgt normalerweise mit Logikpegel (3-5V).

Ich habe geschrieben bis zu 1 Mbps, es ist kein muss. Ohne 12V leuchten die LED-Streifen nicht und der Nano mir nur 5V bereitstellen kann, muss ich extern die 12V herkriegen.

Ahmow:
Ich möchte ein digitalen Signal. Ich versuche es mal mit dem IR-Empfänger. Danke!

Das ist mal eine vernünftige Aussage.

...Ohne 12V leuchten die LED-Streifen nicht und der Nano mir nur 5V bereitstellen kann, muss ich extern die 12V herkriegen.

Nur was hat das mit einem Audio-Verstärker zu tun ?
Du willst doch sicher nicht mit dem Verstärker aus 5 Volt 12 Volt machen ? Oder doch ?

HotSystems:
Das ist mal eine vernünftige Aussage.

Nur was hat das mit einem Audio-Verstärker zu tun ?
Du willst doch sicher nicht mit dem Verstärker aus 5 Volt 12 Volt machen ? Oder doch ?

Nun im Labor haben sie mir es empfohlen. Wobei ich glaube die externen 12 V schon ausreichen würden.

Ahmow:
Nun im Labor haben sie mir es empfohlen. Wobei ich glaube die externen 12 V schon ausreichen würden.

Was haben die empfohlenen ?
Bitte etwas genauer.

HotSystems:
Was haben die empfohlenen ?
Bitte etwas genauer.

Den Audio-Verstärker

Ahmow:
Den Audio-Verstärker

Und wozu soll der gut sein ?

Wer einen Audio-Verstärker zum Betrieb einer LED-Beleuchtung vorschlägt, der weiß sicher auch noch, wie der entsprechende Code dazu aussehen soll. Irgendjemand hat da irgendwas völlig falsch verstanden, und solange das nicht geklärt werden kann, geht es keinen Schritt voran.

Wir wär's für den Anfang mit einem Link zum Datenblatt der LED-Streifen?

DrDiettrich:
Wir wär's für den Anfang mit einem Link zum Datenblatt der LED-Streifen?

Und endlich mal eine genaue Beschreibung was du mit deinem IR-Empfänger erreichen möchtest.

Dieses ewige hin und her ohne korrekte Angaben ist extrem frustrierend.

Und die Erklärung bitte so, dass wir das alle verstehen.