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