efinf:blc2016:bu1:projekt2:projekt

Laserkommunikation - Datenübertragung via Lichtwellen

Teng, Jannis, Luca

Das Ziel des Projekts ist es, mit Lasern Daten zwischen 2 Arduino-Boards auszutauschen.

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.

Für jeden Client wurden folgende Materialien benötigt:

  • 1x Arduino
  • 1x 100Ω Widerstand
  • 1x Trimpot
  • 1x Laser
  • 1x Photodiode

Schema:

1. Version:

2. Version:

3. Version:

Binary-File

Code anzeigen

Code anzeigen

/**
  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);
    }
  }
 
 
}

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.

  • efinf/blc2016/bu1/projekt2/projekt.txt
  • Last modified: 2017/03/17 09:25
  • by jannis_widmer