Hi all,
I am working on a "Li-Fi" - themed project, where my current goal is to transmit a message string serially between two Arduino Nanos, with the physical data line being replaced by a simple LED driver and photodiode receiver circuitry.
I am trying to write a message string in ASCII to a SoftwareSerial defined serial port. The Tx pin for the SoftwareSerial port is used to drive the gate of a 2N7000 that sinks an LED load. The LED strobes are received by op amp circuitry and fed to the input of a comparator as a 1-bit ADC. The result looks something like this for a three character message with newline and carriage return appended:
NOTE: In the above image, the yellow signal trace is the voltage measured directly at the Tx pin of the dedicated transmitting Arduino. The green trace is the voltage measured after amplification and the digitization on the receive end (to be read by a different Arduino). The green trace is inverted via the oscilloscope, and I am using inverted logic in my SoftwareSerial object to (I believe) accomplish the same effect.
I'll also add this; the signal captures with the green trace not inverted (so the signal that the receive Arduino truly sees):
////////
CODE
\\\\\\\\
My code for the transmitted signal (ie the Arduino driving the LED; the yellow trace):
//This program takes a predefined input string and sends it via the software serial
//Tx pin upon the press of a push button input attached to D5
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3
#define buttonPin 5
String password;
String msg = "ffx\n\r";
int pbState = 0;
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
// Define pin modes
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
// Set the baud rate for the SoftwareSerial object
mySerial.begin(115200);
}
void loop() {
password = msg;
//Write hex string to software serial tx pin
if (digitalRead(buttonPin) == 1 & pbState == 0) {
mySerial.print(password);
pbState = 1;
digitalWrite(LED_BUILTIN, HIGH);
}
if (digitalRead(buttonPin) == 0 & pbState == 1) {
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Message sent via software serial...");
delay(10);
pbState = 0;
}
}
It seems for testing as of now this transmit code works fine, but on the receive end, I am seeing a bunch of question marks, despite the fact that the signals look nearly identical when measured (they have a delay between them on the order of a 0.5-2 µs). Here is my code for the reading the received (green trace) photodiode signal:
//This program reads an input string received on a software serial defined
//serial port. The HW serial port is used for debugging means.
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3
String password;
String msg = "Waiting for msg... ";
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin, true);
void setup() {
//Init hardware serial for debugging means
Serial.begin(115200);
// Define pin modes for TX and RX
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// Set the baud rate for the SoftwareSerial object
mySerial.begin(115200);
}
void loop() {
//Print greeting message
Serial.println(msg);
//Wait for a string to be entered
while (mySerial.available() == 0) {}
//Store string
password = mySerial.readString();
//Write hex string to HW serial tx pin
Serial.print(password);
}
And the funny results I was mentioning:
So you can see it looks like it sometimes gets it, sometimes not.
Here's where I'm at:
I don't think the logical inversion has anything to do with it since when chars are recognized, they are the correct ones ('f' and 'x'). This leads me to think its some issue with using readString() on a software serial object, but I also didn't notice a similar problem when the the Arduino's were wired directly together. And full-circle, the signals look so similar that I'm not sure how substituting the Tx line for the LED:Photodiode:amplifier equivalent would cause this. I am looking for guidance as to what could be my issue. Hopefully it is reconcilable without adjusting my hardware setup too much. For example adding a channel for duplexed communication would not be easy.
Thanks for your time.