{{backlinks>.}} ====== Laserkommunikation - Datenübertragung via Lichtwellen ===== ==== Autoren ==== Teng, Jannis, Luca ==== Idee und Fernziel ==== Das Ziel des Projekts ist es, mit Lasern Daten zwischen 2 Arduino-Boards auszutauschen. ==== Minimalprojekt ==== Das Ziel ist die Herstellung eines "Chatprogramms", das über 2 Aurduinos (und die zugehörige Laserverbindung) Daten austauscht. Das Programm funktioniert in beide Richtungen, es ist also sowohl möglich Text zu senden als auch zu empfangen. ===== Bericht ===== ==== Material ==== Für jeden Client wurden folgende Materialien benötigt: * 1x Arduino * 1x 100Ω Widerstand * 1x Trimpot * 1x Laser * 1x Photodiode ==== Aufbau ==== === Schema: === {{:efinf:blc2016:bu1:projekt2:laserkom_bb.png?nolink&600|}} === 1. Version: === {{:efinf:blc2016:bu1:projekt2:version-1.jpeg?nolink&400|}} === 2. Version: === {{:efinf:blc2016:bu1:projekt2:version-2.jpeg?nolink&400|}} === 3. Version: === {{:efinf:blc2016:bu1:projekt2:version-3.jpeg?nolink&400|}} ==== Code ==== [[https://raw.githubusercontent.com/lucanaef/LaserKom/master/LaserKom.ino|Binary-File]] /** Software zur Kommunikation zwischen zwei Lasern mittels Lasern & Photodioden Infos zum Projekt: https://fginfo.ksbg.ch/dokuwiki/doku.php?id=efinf:blc2016:bu1:projekt2:projekt Autoren: Teng Jiang, Luca Näf & Jannis Widmer (KSBG 2017) Funktionsweise: Setup: PINs aktualisieren Senden: Text in Serial Monitor eingeben. Empfangen: Serial Monitor öffnen und Text empfangen **/ // PIN-Vergaben auf den Arduino Boards #define LASERPIN 4 #define PHOTOPIN 3 enum Action { Send, Receive }; class Info { public: Info() { WAITTRUEBIT = 40; WAITFALSEBIT = 20; WAITBIT = 10; WAITAFTERBIT = 10; COUNTBORDER = 15; } int LASER; int PHOTO; int WAITTRUEBIT; int WAITFALSEBIT; int WAITBIT; int WAITAFTERBIT; int COUNTBORDER; }; // Klasse um Datenpakete zu senden class LaserWriter { private: void writeBit(bool t) { digitalWrite(point->LASER, HIGH); if(t) { delay(point->WAITTRUEBIT); } else { delay(point->WAITFALSEBIT); } digitalWrite(point->LASER, LOW); delay(point->WAITBIT); } Info *point; protected: void setInfo(Info *point) { this->point = point; } // Startsignal abwarten void waitForCall() { while(!digitalRead(point->PHOTO)); delay(point->WAITAFTERBIT); } // Funktion um Zeichen zu senden void writeByte(char t) { for(unsigned char st = 0; st < 8; st++) { writeBit(t << st & 0b10000000); } } // Funktion um Integer zu senden void writeInteger(int l) { char t; for(int st = 0; st < sizeof(int); st++) { t = 0; t = t | l; l >> 8; waitForCall(); writeByte(t); } } }; // Klasse um Datenpakete zu empfangen class LaserReader { private: Info *point; protected: void setInfo(Info *point) { this->point = point; } // Funktion um Zeichen zu empfangen: char readChar(){ // Deklarierung und Initilaisierung: int nextbyte = 0; int bitcount = 0; // Startsignal geben: digitalWrite(point->LASER, HIGH); delay(point->WAITAFTERBIT); digitalWrite(point->LASER, LOW); // Bytes Empfangen: for (int c = 0; c<8; c++) { // Bit-Iteration while(not(digitalRead(point->PHOTO))){} // warten bis Signal empfangen wird while(digitalRead(point->PHOTO)){ // Zählen solange Signal vorhanden ist bitcount ++; delay(2); } if (bitcount < point->COUNTBORDER) {nextbyte = nextbyte << 1;} // Auswertung else {nextbyte = nextbyte << 1 | 1;} bitcount = 0; } char c = nextbyte; return c; } // Funktion um Integer zu empfangen: int readInt(){ // Deklarierung und Initilaisierung int nextbyte = 0; int bitcount = 0; // Startsignal geben digitalWrite(point->LASER, HIGH); //Eventuell Problem mit Starter bei Zahlen > 255 delay(point->WAITAFTERBIT); digitalWrite(point->LASER, LOW); // Bytes Empfangen for (int c = 0; c<8; c++) { // Bit-Iteration while(not(digitalRead(point->PHOTO))){} // warten bis Signal empfangen wird while(digitalRead(point->PHOTO)){ // Zählen solange Signal vorhanden ist bitcount ++; delay(2); } if (bitcount < point->COUNTBORDER) {nextbyte = nextbyte << 1;} // Auswertung else {nextbyte = nextbyte << 1 | 1;} bitcount = 0; } return nextbyte; } }; // Protokoll-Klasse um Empfangen und Senden zu vereinbaren class LaserProtoc : LaserWriter, LaserReader { public: LaserProtoc() { LaserWriter::setInfo(&dInfo); LaserReader::setInfo(&dInfo); } // String Senden void sendString(String toSend) { int x = toSend.length(); waitForCall(); writeInteger(x); for(int st = 0; st < x - 1; st++) { waitForCall(); writeByte(toSend[st]); } } // String empfangen String receiveString() { String ret = ""; int x = readInt(); for(int st = 0; st < x; st++) { ret += readChar(); } return ret; } // Funktion um zu Senden und zu Empfangen bool drive(Action &what, String &stringVal) { String h = ""; if(digitalRead(dInfo.PHOTO)) { what = Receive; while(digitalRead(dInfo.PHOTO)); delay(50); stringVal = receiveString(); return true; } h = Serial.readString(); if(h != "") { Serial.println("Senden"); digitalWrite(dInfo.LASER, HIGH); delay(1200); digitalWrite(dInfo.LASER, LOW); sendString(h); Serial.println("Gesendet"); what = Send; stringVal = h; return true; } return false; } void SetLaser(int port) { dInfo.LASER = port; } void SetPhoto(int port) { dInfo.PHOTO = port; } private: Info dInfo; }; LaserProtoc lClass; // PINS initialisieren void setup() { lClass.SetLaser(LASERPIN); pinMode(LASERPIN, OUTPUT); lClass.SetPhoto(PHOTOPIN); pinMode(PHOTOPIN, INPUT); Serial.begin(115200); } void loop() { String l; Action w; if(lClass.drive(w, l)) { if(w == Send) { Serial.print("Gesendet: "); Serial.println(l); } else { Serial.print("Erhalten: "); Serial.print(l); } } } ==== Fazit ==== Mit dem Programm ist es nun möglich zwischen 2 Computern mit Hilfe der Arduinos über Laserkommunikation zu chatten (Dabei können beide Sender und Receiver sein). Die Verzögerung ist sehr Hoch, da die Infomationen bit-weise transportiert werden. D. h. bei einem langen Satz wird die Wartenszeit deutlich merkbar. Die maximale Reichweite wurde nicht überprüft, da es viel zu schwerig war, die Photodiode mit dem Laser zu treffen. ==== Fotos und Film ==== {{:efinf:blc2016:bu1:projekt2:demonstration.jpeg?nolink&800|}}