#include <cstring> // Per strlen()
#define FLASHLEDPIN 4
#define SAMPLE_PER_SYMBOL 4
#define DATA_LEN 40
//unsigned int inputSignal = 0xABCD1234;
enum receiver_state {
IDLE, //waiting for sync
SYNC, //synced, waiting for STX
START, //STX received
DATA //receiving DATA
};
enum receiver_state frame_state = IDLE;
volatile unsigned int contatore = 0; // Indica quale bit del segnale leggere
volatile unsigned int subcontatore = 0; // Contatore per la durata del simbolo
char* segnale = "10100110101010100101"; // Stringa binaria del segnale
unsigned char getNextBit() {
// Restituisce il bit corrente (1 o 0) come unsigned char
//Serial.print("sub,cont:");
//Serial.print(subcontatore);
//Serial.print("-");
//Serial.println(contatore);
// Incrementa il contatore secondario (subcontatore)
if (subcontatore == SAMPLE_PER_SYMBOL) {
subcontatore=0;
contatore++;
if (contatore == strlen(segnale)) {
contatore = 0; // Riprendi dall'inizio se il segnale è terminato
}
}
subcontatore++; // Continua a restituire lo stesso bit
if (segnale[contatore] == '1') {
return 0x1; // Bit alto
} else {
return 0x0; // Bit basso
}
}
#define IDLE_TIME 20
#define START_SYMBOL 0x02
#define STOP_SYMBOL 0x01
#define START_STOP_MASK ((STOP_SYMBOL << 20) | (START_SYMBOL << 18) | STOP_SYMBOL) //STOP/START/16bits/STOP
#define SYNC_SYMBOL_MANCHESTER (0x6665)
inline int is_a_word(volatile long *manchester_word, int time_from_last_sync, volatile unsigned int *detected_word) {
if (time_from_last_sync >= IDLE_TIME || frame_state == IDLE) { // we received enough bits to test the sync
if (((*manchester_word) & START_STOP_MASK) == (START_STOP_MASK)){ // testing first position
(*detected_word) = ((*manchester_word) >> 2) & 0xFFFF;
if (frame_state == IDLE) {
if ((*detected_word) == SYNC_SYMBOL_MANCHESTER)
return 2;
}
return 1;
// byte with correct framing
} else if (frame_state != IDLE && time_from_last_sync == IDLE_TIME) {
(*detected_word) = ((*manchester_word) >> 2) & 0xFFFF;
return 1;
}
}
return 0;
}
inline int insert_edge(volatile long *manchester_word, signed char edge, int edge_period, volatile int *time_from_last_sync, volatile unsigned int *detected_word) {
int new_word = 0;
int is_a_word_value = 0;
int sync_word_detect = 0;
if (((*manchester_word) & 0x01) != edge) { //mak sure we don't have same edge ...
if (edge_period > (SAMPLE_PER_SYMBOL + 1)) { // se ci troviamo di fronte a scenari 00 o 11
Serial.print("*|");
unsigned char last_bit = (*manchester_word) & 0x01; //Aggiunge l'ultimo bit
//Siccome la successione stopstart comporta andare incontro a situazioni 11 allora quandi stiamo in questa situazione puo' essere che e' inizata una nuova parola (un char + start + stop)
(*manchester_word) = ((*manchester_word) << 1) | last_bit; // signal was steady for longer than a single symbol,
(*time_from_last_sync) += 1;
is_a_word_value = is_a_word(manchester_word, (*time_from_last_sync), detected_word);
if (is_a_word_value > 0) { //found start stop framing
new_word = 1;
(*time_from_last_sync) = 0;
if (is_a_word_value > 1) sync_word_detect = 1; //we detected framing and sync word in manchester format
}
}
//storing edge value in word
if (edge < 0) {
Serial.print("Z|");
(*manchester_word) = ((*manchester_word) << 1) | 0x00; // signal goes down
} else {
Serial.print("U|");
(*manchester_word) = ((*manchester_word) << 1) | 0x01; // signal goes up
}
(*time_from_last_sync) += 1;
is_a_word_value = is_a_word(manchester_word, (*time_from_last_sync), detected_word);
if (sync_word_detect == 0 && is_a_word_value > 0) { //if sync word was detected at previous position, don't take word detection into account
new_word = 1;
(*time_from_last_sync) = 0;
}
} else {
new_word = -1;
}
return new_word;
}
volatile long shift_reg = 0;
volatile int dist_last_sync = 0;
volatile unsigned int detected_word = 0;
volatile int new_word = 0;
//inline int insert_edge(volatile long *manchester_word, signed int edge, int edge_period, volatile int *time_from_last_sync, volatile unsigned int *detected_word){
// return(-1);
//}
volatile unsigned int newbit =0;
volatile unsigned int oldbit =0;
volatile unsigned int symbol_memory =0;
volatile unsigned int symbol_memory_count1 =0;
volatile int edge_val =0;
hw_timer_t *timerRX = NULL;
void ICACHE_RAM_ATTR timer3RX_ISR(void) {
unsigned int now = millis();
newbit = getNextBit();
Serial.print("Letto segnale:");
Serial.println(newbit);
digitalWrite(FLASHLEDPIN, newbit);
if (true) {
if (newbit > oldbit) {
symbol_memory = 1;
symbol_memory_count1 = 0;
edge_val = 1;
oldbit = newbit;
} else if (oldbit > newbit) {
symbol_memory = -1;
symbol_memory_count1 = 0;
edge_val = -1;
oldbit = newbit;
} else {
edge_val = 0;
symbol_memory_count1 = symbol_memory_count1 + 1;
}
}
Serial.print("Edge(");
Serial.print(edge_val);
Serial.print(") BitRepeated(");
Serial.print(symbol_memory);
Serial.print(") Repetition(");
Serial.print(symbol_memory_count1);
Serial.println(")");
}
volatile int oldValue = 0;
volatile int steady_count = 0;
volatile int old_edge_val = 0;
volatile int symbol_memory_count = 3;
volatile unsigned int sensorValue =0;
void ICACHE_RAM_ATTR timerRX_ISR(void) {
unsigned int now = millis();
newbit = getNextBit();
sensorValue=newbit;
digitalWrite(FLASHLEDPIN, newbit);
if (symbol_memory_count > 4 && symbol_memory_count < 7) {
Serial.println("sonoqui");
edge_val = 0;
symbol_memory_count++;
} else {
if (sensorValue > oldValue) {
symbol_memory = 1;
symbol_memory_count = 0;
edge_val = 1;
oldValue = sensorValue;
} else if (oldValue > sensorValue) {
symbol_memory = 0;
symbol_memory_count = 0;
edge_val = -1;
oldValue = sensorValue;
} else {
edge_val = 0;
symbol_memory_count =0;
}
}
Serial.print(sensorValue);
Serial.print("|");
Serial.print(edge_val);
Serial.print("|");
if (edge_val == 0 || edge_val == old_edge_val || (edge_val != old_edge_val && steady_count < 2)) {
if (steady_count < (2 * SAMPLE_PER_SYMBOL)) {
steady_count++;
}
Serial.print(steady_count);
Serial.print("|");
} else {
Serial.print("INSERT");
Serial.print("|");
new_word = insert_edge(&shift_reg, edge_val, steady_count, &dist_last_sync, &detected_word);
if (dist_last_sync > (4 * SAMPLE_PER_SYMBOL)) {
dist_last_sync = DATA_LEN;
}
if (new_word >= 0) {
steady_count = 0;
}
}
Serial.print(new_word);
Serial.print("|");
Serial.print(dist_last_sync);
Serial.print("|");
Serial.print(shift_reg,BIN);
Serial.print("|");
Serial.print("|");
Serial.println(dist_last_sync);
old_edge_val = edge_val;
}
void setup() {
Serial.begin(115200);
pinMode(FLASHLEDPIN, OUTPUT);
Serial.println("Started with signal:");
//Serial.println(inputSignal,BIN);
//adc1_config_width(ADC_WIDTH_12Bit); //ko per esp32cam
for (int i=0; i< strlen(segnale); i++){
Serial.print(segnale[i]);
}
Serial.println("\nSamples:");
contatore=0;
subcontatore=0;
for (int i=0; i<= (strlen(segnale)-1)*SAMPLE_PER_SYMBOL; i++){
Serial.print(getNextBit());
}
contatore=0;
subcontatore=0;
Serial.println("---");
delay(1000);
timerRX = timerBegin(1000000);
timerAttachInterrupt(timerRX, &timerRX_ISR);
timerAlarm(timerRX, 5000000, true,0);
//timer2RX = timerBegin(0, 80, true); // use tiemr 0 and set prescale to 80 so 1 tick is 1 uSec
//timerAttachInterrupt(timer2RX, &timer2RX_ISR, true); // point to the ISR
//timerAlarmWrite(timer2RX, 1000000, true); // set alarm every 1 sec
//timerAlarmEnable(timer2RX); // enable the alarm
Serial.println("S|E|SC|NW|DLS");
}
void loop() {
//Serial.print(getNextBit());
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}