Как данные передаются? Манчестером?
Здравствуйте! Почитал гугл. Действительно, данные передаются Манчестерским кодированием. Вот код моей программы для передатчика. Я так понимаю, что вся проблема в интервалах времени ДЛЯ ПЕРЕДАТЧИКА. Нужно эти интервалы менять, только я пока не знаю как.
#include <VirtualWire.h>
#define txPin 3 // цифра 3 - это номер ноги, к которой подключается контакт data передатчика.
#define Te 320
const int led_pin = 13;//сигнальный светодиод
void setup(){
pinMode(txPin, OUTPUT); // настраиваем ногу txPin, т.е. ногу №3 как выход
}
void loop()
{
SendCame(0b101010101010101010101010); //пока такой код передаем (в HEX АААААА). Принимается сообщение как 010101010101010101010101 (в HEX это 555555). В действительности будет код 1111 1111 0100 1111 1111 0100 как обозначено в топике.
}
void SendCameBit(byte b) // 0 передается 2-мя высокими интервалами, 1-м низким интервалом
{
delayMicroseconds(Te);
if (!b) digitalWrite(txPin,HIGH);
delayMicroseconds(Te);
digitalWrite(txPin,HIGH);
delayMicroseconds(Te);
digitalWrite(txPin,LOW);
}
void SendCame(long Code)
{
digitalWrite(led_pin, HIGH); // Зажигаем светодиод в начале передачи
for (int j=0;j<4;j++) // посылку посылаем как 4 раза подряд, т.к. посылка может потеряться из-за ЭМ помех.
{
digitalWrite(txPin,HIGH);
delayMicroseconds(Te);
digitalWrite(txPin,LOW);// посылаем стартовый импульс
for (byte i=24;i>0;i--)
{
SendCameBit(bitRead(Code, i-1)); // побитово перебираем и посылаем код
}
delay(10); //здесь большое значение времени >300 вообще сигнал не принимается. Почему?
}
vw_wait_tx(); // Ожидаем окончания отправки сообщения
digitalWrite(led_pin, LOW); // Гасим светодиод в конце передачи
delay(1500); // сделать паузу после посылки на 1,5 мс
}
Вот код приемника. К ардуине с приемником подключен дисплей для вывода сообщения:
//программа для дисплея. RST - D6, CE - D7, DC - D5, DIN - D4, CLK - D3
#include <VirtualWire.h>
#include <PCD8544.h>
#define RX 2
#define TIMER_DIV
static PCD8544 lcd;
static int counter = 1;//счетчик для подсчета количества полученных сообщений
volatile byte level=255;
volatile unsigned long last=0, len;
byte p_level;
unsigned long p_len, p_len_prev;
struct
{
uint8_t state;
uint8_t data[3], dat_bit;
} came;
void set_bit(uint8_t *data, uint8_t n)
{
data[n/8]|=1<<(n%8);
}
#define CM_MAX_TE 450
#define CM_MIN_TE 250
#define CM_BITS12 12
#define CM_BITS24 24
void process_came()
{
unsigned char b;
switch(came.state)
{
case 0:
if(p_level) break;
came.state=1;
break;
case 1: //start
if(!p_level) break;
else if(p_len>=CM_MIN_TE && p_len<=CM_MAX_TE)
{
came.state=2;
came.dat_bit=0;
came.data[0]=0x00;
came.data[1]=0x00;
came.data[2]=0x00;
}
else came.state=0;
case 2: //dat
if(p_level)
{
if(came.dat_bit==CM_BITS24)
{
came.state=0;
break;
}
if(p_len_prev<=CM_MAX_TE && p_len_prev>=CM_MIN_TE &&
p_len<=CM_MAX_TE*2 && p_len>=CM_MIN_TE*2) b=0;
else
if(p_len_prev<=CM_MAX_TE*2 && p_len_prev>=CM_MIN_TE*2 &&
p_len<=CM_MAX_TE && p_len>=CM_MIN_TE) b=1;
else
{
came.state=0;
break;
}
if(b) set_bit(came.data, came.dat_bit);
came.dat_bit++;
break;
}
else
{
if((p_len>5000)&&(came.dat_bit==CM_BITS12 || came.dat_bit==CM_BITS24)) came.state=100;
}
break;
}
}
void dump_hex(byte *buf, byte bits) //выводит каждое сообщение на новой строке монитора порта, в дисплее ничего не меняется
{
byte b;
for(b=0; b>(bits+7)/8; b++)
{
if(buf[b]>0x0f) Serial.print('0');
Serial.print(buf[b], HEX);
Serial.print(" ");
}
Serial.println("");
}
void rx_int()
{
if(level!=255) return;
len=micros()-last; //micros - возвращает количество микросекунд с момента начала выполнения текущей программы
last=micros();
if(digitalRead(RX)==HIGH) level=0;
else level=1;
}
void setup()
{
attachInterrupt(0, rx_int, CHANGE); //служит для прерывания (внешнего прерывания с обработчиком), где 0 - номер вызываемого прерывания для 2 пина;
//rx_int - функция, вызываемая прерыванием, CHANGE - условие срабатывания (изменение сигнала с высокого на низкий или обратно)
Serial.begin(9600);
while(!Serial);
Serial.println("MEGA ARDUINO LOGGER");
Serial.println("");
interrupts();
lcd.begin(84, 48);
lcd.setCursor(0, 0);
lcd.print(" Receiver "); // "Приемник"
lcd.print(" is ready!"); // "готов!"
}
//byte b;
void loop()
{
if(level!=255)
{
noInterrupts(); //запрещает прерывания. Далее идет критичный ко времени участок кода.
p_level=level;
p_len=len;
len=0;
level=255;
interrupts(); // разрешает прерывания.
process_came();
p_len_prev = p_len;
}
if(came.state==100)
{
Serial.print(came.data[0],HEX);
Serial.print(came.data[1],HEX);
Serial.print(came.data[2],HEX);
//Serial.print("CAME[");
Serial.print("came[");
Serial.print(came.dat_bit);
Serial.print("]: ");
lcd.setCursor(0, 3);
lcd.print(counter);
lcd.print(" ");
lcd.print(came.data[0],HEX);
lcd.print(came.data[1],HEX);
lcd.print(came.data[2],HEX);
dump_hex(came.data, came.dat_bit);
came.state=0;
counter++;
}
}
Добавлено after 13 minutes 39 seconds: