Картинка в тему (вчера бы была более нужной
)
И вот тут говорится, что изначально в этом протоколе посылается серия 101010, чтобы приемное устройство вычислило длительность импульса (клок).
А что сложного вот в этой библиотеке то?
Там же только пин указать и скорость (последнее попробовать перебором) man.setupReceive(RX_PIN, MAN_9600);
#include "Manchester.h"
/*
Manchester Receiver example
In this example receiver will receive array of 10 bytes per transmittion
try different speeds using this constants, your maximum possible speed will
depend on various factors like transmitter type, distance, microcontroller speed, ...
MAN_300 0
MAN_600 1
MAN_1200 2
MAN_2400 3
MAN_4800 4
MAN_9600 5
MAN_19200 6
MAN_38400 7
*/
#define RX_PIN 4
#define LED_PIN 13
uint8_t moo = 1;
#define BUFFER_SIZE 22
uint8_t buffer[BUFFER_SIZE];
void setup()
{
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, moo);
Serial.begin(19200);
man.setupReceive(RX_PIN, MAN_9600);
man.beginReceiveArray(BUFFER_SIZE, buffer);
}
void loop()
{
if (man.receiveComplete())
{
uint8_t receivedSize = 0;
//do something with the data in 'buffer' here before you start receiving to the same buffer again
receivedSize = buffer[0];
for(uint8_t i=1; i<receivedSize; i++)
Serial.write(buffer[i]);
Serial.println();
man.beginReceiveArray(BUFFER_SIZE, buffer);
moo = ++moo % 2;
digitalWrite(LED_PIN, moo);
}
}
А… У неё из ESP только ESP8266… ESP32 нужно добавлять поддержку.
вот на картинке немного мозг ломается: manchester = ~ (clock ^ data); верно же понимаю? но чет в статьях, которые попадались об этом инфы не увидел при беглом изучении. Получается, можно в прерывании сразу данными набивать, если малость обмозговать принцип действия, там минимум операций будет.
Ага, и обратное преобразование ровно так же реализуется: data = ~ (clock ^ manchester);
Увлекательная какая ветка… " Закат Солнца вручную"
инверсия закодированных битов
Но есть нюанс.
Клока нет.
Вместо этого предлагается синхронизироваться по какому-то импульсу\преамбуле.
Синхронизация только по фазе. По клоку синхронизация не нужна.
более того, в реализации, которую родил, нет даже чтения входов, только дельты времени между изменением состояния порта…
Я именно так и сделал. На выходе ничего не было если правильно помню.
Я её и на Ардуино нано пробовал. Не заработала. Потом заглянул в Manchester.h
и понял, и там крутить надо под конкретный случай.
Вот это тоже пробовал
https://github.com/victornpb/manch_decode?tab=readme-ov-file
Доброго! Надо нам кое-чего попробовать…
#define BTNPIN 2
uint16_t width = 200; // длительность полупериода CLK
uint32_t RES1, RES2; // результаты
bool fresh = false; // "свежие" ли данные
//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {
static uint32_t last = 0;
static uint16_t i = 0;
static bool bit = true;
static bool second = false;
static uint32_t _RES1, _RES2;
static uint32_t* p_res = &_RES1;
uint32_t current= micros();
uint32_t dt = current - last;
last = current;
if (dt < width * 1.5) {
// для каждого четного пишем бит
if (i % 2 == 0) *p_res |= (uint32_t)bit << (i / 2);
// инкремент
i++;
} else if (dt < width * 2.5) {
// инкриментим сразу на 2
i += 2;
// пишем ПЕРЕД инверсией бита
*p_res |= (uint32_t)bit << (i / 2);
// длинная пауза меняет бит
bit = !bit;
} else if (dt < width * 3.5) {
// так не бывает
} else if (dt < width * 4.5) {
// начало записи регистра
i = 0;
bit = true;
p_res = second ? &_RES2 : &_RES1;
*p_res = 0;
second = false;
} else if (dt < width * 5.5) {
// следующий пакет будет во второй регистр
second = true;
} else {
// длинная пауза - пишем в глобальные переменные
RES1 = _RES1;
RES2 = _RES2;
fresh = RES1 == RES2;
}
}
void setup() {
pinMode(BTNPIN, INPUT_PULLUP);
Serial.begin(115200);
attachInterrupt(0, chng, CHANGE);
}
void loop() {
if (fresh) {
fresh = false;
// вычленяем результаты
uint8_t A = (uint32_t)RES1 >> 1 ;
uint8_t B = (uint32_t)RES1 >> 9 ;
uint8_t C = (uint32_t)RES1 >> 17;
uint8_t A2 = (uint32_t)RES2 >> 1 ;
uint8_t B2 = (uint32_t)RES2 >> 9 ;
uint8_t C2 = (uint32_t)RES2 >> 17;
Serial.print(RES1, BIN);
Serial.print(' ');
Serial.println(RES2, BIN);
Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2));
}
}


