Created
February 17, 2017 01:18
-
-
Save wlmeng11/469243778975754bf650ea086240798c to your computer and use it in GitHub Desktop.
Laser UART Transmitter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Laser UART Receiver | |
| * William Meng | |
| * 2/16/17 | |
| * | |
| * Based on "Gateway_better_code_receive.ino" by Sean Zimmermann | |
| * | |
| * What's new in this version: | |
| * The program has been updated to work better with the laser | |
| * transmitter and solar cell receiver circuit. The bitrate has been | |
| * reduced to 10 bits per second so you can actually see the laser | |
| * pulses. Additionally, the idle state has been changed to be an | |
| * alternating sequence of HIGHs and LOWs so that the capacitor | |
| * voltage in the receiver circuit doesn't drift too close to the | |
| * HIGH or LOW voltages, which caused erratic oscillations. | |
| * | |
| * This required a lot of changes in the control flow in terms of | |
| * how and when to detect a start bit. | |
| */ | |
| #define IDLE_TIME 100 | |
| #define STOP_IDLE_TIME 200 // must be longer than IDLE_TIME | |
| #define BIT_TIME 100 // 1 bit per 100ms | |
| #define WAIT_CYCLES 1 | |
| #define WAIT_PERIOD WAIT_CYCLES*IDLE_TIME | |
| #define RX_PIN 6 | |
| #define TX_PIN 7 | |
| void setup() { | |
| pinMode(RX_PIN, INPUT_PULLUP); | |
| pinMode(TX_PIN, OUTPUT); | |
| digitalWrite(TX_PIN, HIGH); | |
| Serial.begin(9600); | |
| } | |
| /** | |
| * Receive the data | |
| * Wait for and identify the stop idle signal, wait for the start bit, | |
| * then wait until the midpoint of each data bit to sample. | |
| */ | |
| void receive() { | |
| byte data = 0; | |
| //Serial.println("Begin receive function"); | |
| while(detect_stop_idle() == 0) {} | |
| while(digitalRead(RX_PIN) == HIGH) {}// wait for the start bit | |
| delay(BIT_TIME/2); // wait until midpoint of start bit | |
| for(int offset = 0; offset < 8; offset++) { | |
| delay(BIT_TIME); | |
| data |= digitalRead(RX_PIN) << offset; | |
| } | |
| //Serial.print("Data: "); | |
| Serial.print((char)data); // convert byte to char | |
| delay(IDLE_TIME); | |
| } | |
| /** | |
| * Returns true if a stop idle signal has been received. | |
| * Returns false means the signal is still idling. | |
| */ | |
| int detect_stop_idle() { | |
| while(digitalRead(RX_PIN) == 0) {} | |
| delay(IDLE_TIME*3/2); | |
| if(digitalRead(RX_PIN)) { | |
| //Serial.println("STOP idling"); | |
| return 1; | |
| } | |
| else { | |
| //Serial.println("I"); | |
| return 0; | |
| } | |
| } | |
| /* | |
| * Prints 1's and 0's every 20ms to serve as a very crude logic | |
| * analyzer, for debugging purposes. | |
| */ | |
| void printRaw() { | |
| Serial.print(digitalRead(RX_PIN)); | |
| delay(20); | |
| } | |
| void loop() { | |
| receive(); | |
| //printRaw(); | |
| //detect_stop_idle(); | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Laser UART Transmitter | |
| * William Meng | |
| * 2/16/17 | |
| * | |
| * Based on "Gateway_better_code_receive.ino" by Sean Zimmermann | |
| * | |
| * What's new in this version: | |
| * The program has been updated to work better with the laser | |
| * transmitter and solar cell receiver circuit. The bitrate has been | |
| * reduced to 10 bits per second so you can actually see the laser | |
| * pulses. Additionally, the idle state has been changed to be an | |
| * alternating sequence of HIGHs and LOWs so that the capacitor | |
| * voltage in the receiver circuit doesn't drift too close to the | |
| * HIGH or LOW voltages, which caused erratic oscillations. | |
| * | |
| * This required a lot of changes in the control flow in terms of | |
| * how and when to detect a start bit. | |
| */ | |
| #define IDLE_TIME 100 | |
| #define STOP_IDLE_TIME 200 // must be longer than IDLE_TIME | |
| #define BIT_TIME 100 // 1 bit per 100ms | |
| #define WAIT_CYCLES 1 | |
| #define WAIT_PERIOD WAIT_CYCLES*IDLE_TIME | |
| #define RX_PIN 6 | |
| #define TX_PIN 7 | |
| void setup() { | |
| pinMode(RX_PIN, INPUT); | |
| pinMode(TX_PIN, OUTPUT); | |
| digitalWrite(TX_PIN, HIGH); | |
| Serial.begin(9600); | |
| } | |
| /* | |
| * Transmit a strictly alternating series of 1's and 0's while idling | |
| * Each bit has a duration of IDLE_TIME | |
| */ | |
| void idle() { | |
| digitalWrite(TX_PIN, HIGH); | |
| delay(IDLE_TIME); | |
| digitalWrite(TX_PIN, LOW); | |
| delay(IDLE_TIME); | |
| } | |
| /* | |
| * Transmit the data, but first send a stop idle signal and the start bit | |
| */ | |
| void transmit(byte data) { | |
| // transmit a stop idle bit | |
| digitalWrite(TX_PIN, HIGH); | |
| delay(STOP_IDLE_TIME); | |
| // transmit the start bit | |
| digitalWrite(TX_PIN, LOW); | |
| delay(BIT_TIME); | |
| byte mask; | |
| for (mask = 0x01; mask>0; mask <<= 1) { // iterate through bit mask | |
| if (data & mask){ // compare the bits | |
| digitalWrite(TX_PIN,HIGH); // send 1 | |
| } | |
| else{ | |
| digitalWrite(TX_PIN,LOW); // send 0 | |
| } | |
| //delayMicroseconds(bit9600Delay); //hold for one bit cycle | |
| delay(BIT_TIME); | |
| } | |
| // idle for the wait period | |
| for (int i = 0; i < WAIT_CYCLES; i++) { | |
| idle(); | |
| } | |
| } | |
| void transmitV() { | |
| // transmit a stop idle bit | |
| digitalWrite(TX_PIN, HIGH); | |
| delay(STOP_IDLE_TIME); | |
| // transmit the start bit | |
| digitalWrite(TX_PIN, LOW); | |
| delay(BIT_TIME); | |
| // transmit data for V | |
| digitalWrite(TX_PIN, LOW); // 0 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, HIGH); // 1 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, LOW); // 0 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, HIGH); // 1 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, LOW); // 0 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, HIGH); // 1 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, HIGH); // 1 | |
| delay(BIT_TIME); | |
| digitalWrite(TX_PIN, LOW); // 0 | |
| delay(BIT_TIME); | |
| } | |
| void loop() { | |
| if (Serial.available() > 0) { | |
| // Required delay to enable re_transmit | |
| // More retransmits may require higher | |
| // delay. Can be commented out if no | |
| // retransmits are used to achieve higher | |
| // speed. | |
| //delayMicroseconds(per_letter_delay); | |
| // read the incoming byte: | |
| byte data = Serial.read(); | |
| // say what you got: | |
| Serial.print("I am sending: "); | |
| Serial.println((char)data); | |
| // if you do Serial.println(SWval, DEC); | |
| // then you can see the ASCII code | |
| transmit(data); //send it out | |
| } | |
| else { | |
| idle(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment