Синхронизация и реализация кода Хэмминга на программном последовательном порту
Я хочу изучить и использовать код Хэмминга. Будет ли разумно… изменить библиотеку последовательного интерфейса программного обеспечения, чтобы сделать это, или просто изменить данные, которые передано в реальном скетче Arduino?
Кроме того, какой метод лучше всего подходит для лучшей синхронизации этих модулей передачи/приёма (tx/rx) с Arduino через программный последовательный порт? Обязан ли я использовать встроенную синхронизацию из библиотеки или могу реализовать другие формы синхронизации, например, кодирование Manchester и NRZ? Если да, то есть ли какие-либо рекомендации?
РЕДАКТИРОВАТЬ
Что делать, если помехи возникают в бите чётности при реализации кода Хэмминга? Есть ли способ обойти эту проблему?
@Jonathan, 👍1
3 ответа
Лучший ответ:
Это может выглядеть примерно так:
class HammingStream : public Stream {
public:
HammingStream(Stream& ios) : m_ios(ios) {}
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
protected:
Stream& m_ios;
uint8_t encode4(uint8_t nibble);
uint8_t decode8(uint8_t code);
};
size_t HammingStream::write(uint8_t byte)
{
m_ios.write(encode4(byte >> 4));
m_ios.write(encode4(byte & 0xf));
return (1);
}
int HammingStream::read()
{
if (available() == 0) return (-1);
uint8_t nibble = decode8(m_ios.read());
return ((nibble << 4) | decode8(m_ios.read());
}
int HammingStream::available()
{
return (m_ios.available() / 2);
}
void HammingStream::flush()
{
m_ios.flush();
}
Тогда вы могли бы:
HammingStream HammingSerial(SoftwareSerial);
HammingSerial.println(F("hello world"));
Вышеизложенное не включает кодирование/декодирование, а также обнаружение ошибок. Декодирование Хэмминга может обнаруживать до двух битовых ошибок и исправлять один бит (для 4-битных данных).
Пример реализации кодера можно найти в Cosa. Здесь используется код Хэмминга (8, 4) для повышения производительности VirtualWire. Обратите внимание, что таблица кодера настроена на радиочастотный сигнал и не допускает постоянного тока (т.е. длительных периодов нуля или единицы).
Ура!
SoftwareSerial может передавать и принимать только пакеты в формате EIA-232. Именно для этого он и предназначен, и именно это он и делает.
Он не может передавать никакой другой формат.
Если вы хотите использовать другие методы кодирования, вам придется использовать метод, отличный от SoftwareSerial.
Для этого может потребоваться написание собственных процедур обработки битов в вашем скетче или в вашей собственной библиотеке, либо использование SoftwareSerial в качестве основы для адаптации в вашу собственную библиотеку.
Обратите внимание, что библиотека SoftwareSerial написана таким образом, что пакеты EIA-232 являются обязательным требованием — задний фронт стартового бита запускает прием одного пакета — любая другая кодировка, не имеющая такого рода расположения стартовых битов, потребует совершенно иного метода организации приема.
Вы можете использовать эту информацию и код: Хэмминг(8,4) с Arduino.
Имеется PDF-файл с документацией о процессе создания класса, реализующего хэмминг(8,4), и ссылкой на исходный код.
Вы можете использовать любой класс, производный от Stream (например, Serial или SoftwareSerial).
Дополнение: Если вы хотите реализовать код Хэмминга ECC в Arduino, будет полезно предварительно вычислить все возможные значения сообщения (подробнее по ссылке выше). В коде Хэмминга (8,4) ваше сообщение — это 1 байт = 4 бита + 4 бита чётности; поэтому вам придётся разбить байты на полубайты. Лучше поместить всё это (кодирование, декодирование, управление старшей/нижней частью байта и т. д.) в класс. Пример использования класса Хэмминга по ссылке выше:
Текст:
#include <hamming.h>
Hamming hamming(&Serial);
char message[] = "Hello World!!";
void setup()
{
Serial.begin(9600);
delay(100);
}
void loop()
{
hamming.write(message);
delay(1000);
}
Рецепт:
#include <hamming.h>
Hamming hamming(&Serial);
char message[Hamming::SIZE];
void setup()
{
Serial.begin(9600);
delay(100);
}
void loop()
{
if(hamming.isMessageReady())
{
hamming.read(message);
Serial.println(message);
}
}
Если вам нужно отправить другой тип информации: число с плавающей точкой, целое число... вы можете это сделать, но я думаю, что лучше токенизировать/детокенизировать вашу информацию и обрабатывать ее как «строку».
P.S. Вы можете использовать любой тип физического уровня, являющийся дочерним для Stream: Serial, SoftwareSerial... Но я тестировал только на Serial.
Это хорошая ссылка. Однако, на случай, если ссылка в будущем перестанет работать, было бы неплохо, если бы вы отредактировали свой ответ, включив в него _краткое изложение_ информации и основную часть необходимого кода., @Greenonline
- Как связаться с GPS SIM900a без serial monitor
- Последовательная связь между nodemcu и Arduino Uno
- Как отправить команду на Gsm модуль из Arduino через последовательный порт
- Последовательная связь между Arduino
- SIM900 к коммутатору
- AT-команда не отвечает на последовательный монитор
- Как заставить Arduino взаимодействовать с тремя другими Ардуино?
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
Итак, я мог бы просто создать простую функцию в своём скетче, которая при передаче числа автоматически реорганизует блок данных, добавляя в него биты чётности. А затем передаст эти новые данные, как будто это просто полезная нагрузка. А затем я могу заставить скетч-приёмник принять эти данные и обработать их в другой функции внутри скетча, верно? Или это было бы неразумно?, @Jonathan
Я бы предпочёл создать собственную библиотеку. Но будет ли эта библиотека просто реструктурировать данные и вызывать функцию записи SoftwareSerial (по сути, то же самое, что я описал выше)? Или мне придётся полностью переделывать функцию записи?, @Jonathan
Здравствуйте, можете ли вы дать мне какие-нибудь советы по поводу моего EDIT? И ещё, не будет ли разумнее вообще не использовать кодировку NRZ на Arduino? @Majenko, @Jonathan