#include <LiquidCrystal.h>
/* Digital data pin and set up for LCD display */
#define data 2
#define rs 3
#define en 4
#define b4 8
#define b5 5
#define b6 11
#define b7 12
LiquidCrystal lcd(rs, en, b4, b5, b6, b7);
/* Time period of one bit of data and size of a sequence */
const uint16_t period = 10000;
const uint8_t size = 16;
/* Start and end sequence for data transfer */
//const uint16_t begin = 0b0000111111110000;
//const uint16_t end = 0b0000111100001111;
const uint16_t begin = 0b1010101010101010;
const uint16_t end = 0b0000111100001111;
/* Buffer for samples */
uint16_t readings;
/* Reference time of begin of sampling */
unsigned long reference;
unsigned long sampleTime;
bool reset = true;
bool start = false;
/* Check for equality of two sequences */
bool equals(const uint16_t sequence) {
return readings == sequence;
}
/* Left rotate the buffer by n */
void rotate() {
readings = (readings << 1) | (readings >> (size - 1));
}
/* Set last element of buffer with sample */
void setLSB(uint8_t sample) {
readings |= (sample & 0x01);
}
/* Set a reference point for sampling */
void setReference() {
volatile uint8_t* dataPort = portInputRegister(digitalPinToPort(data));
uint8_t dataBit = digitalPinToBitMask(data);
while ((*dataPort & dataBit) == 0) {}
while ((*dataPort & dataBit) != 0) {}
reset = false;
reference = micros();
}
/* Get new sample based on known data frequancy, INPUT is inverted! */
uint8_t getSample() {
uint8_t sample;
sampleTime = reference + (period >> 1);
while (micros() < sampleTime) {}
sample = digitalRead(data);
reference += period;
return (sample ^ 0x01);
}
/* Wait for begin sequence and fill buffer with samples */
uint8_t getSequence() {
if (reset)
setReference();
while (!start) {
if (equals(begin))
start = true;
rotate();
setLSB(getSample());
}
for (uint8_t i = 0; i < size; i++) {
rotate();
setLSB(getSample());
}
Serial.println(readings, BIN);
return readings;
}
/* Decode a modulated sequence */
uint8_t decodeManchester(uint16_t encoded) {
uint8_t decoded = 0;
if ((encoded >> size - 2) == 0x0001)
return 0x24;
for (uint8_t i = 0; i < (size >> 1); i++) {
uint8_t maskedLSB = encoded & 0x03;
if (encoded & 0x0001)
decoded |= (1 << i);
encoded >>= 2;
if (maskedLSB == 0x03 || maskedLSB == 0x00)
return 0x25;
}
return decoded;
}
/* Create a string from given characters */
char* createString() {
char message[size + 1];
for (uint8_t i = 0; i < size; i++) {
char c = decodeManchester(getSequence());
message[i] = c;
}
message[size + 1] = '\0';
return message;
}
void setPWM() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TCNT1 = 0;
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= _BV(CS12) | _BV(CS10); // Set prescaler to 1024
ICR1 = 156; // Output frequency = CLK frequency / (prescaling factor * ICR1), TNCNT1 = TOP
OCR1A = 78; // Duty cycle = (ICR1 - OCR1A) / ICR1), corresponds to Arduino Nano output 9
TCCR1A |= _BV(COM1A1) | _BV(COM1A0);
OCR1B = 78; // Duty cycle = OCR1B / ICR1, corresponds to Arduino Nano output 10
TCCR1A |= _BV(COM1B1);
TCCR1B |= _BV(WGM13);
TCCR1A |= _BV(WGM11);
}
void setup() {
// put your setup code here, to run once:
delay(2000);
Serial.begin(9600);
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
setPWM();
}
unsigned long startTime;
unsigned long difference;
void loop() {
// startTime = micros();
// for (int i = 0; i < 5; i++) {
// char decoded = decodeManchester(encoded[i]);
// str[i] = decoded;
// Serial.print(decoded);
// }
// Serial.println();
lcd.print(createString());
}