Задать вопрос
@ustivanon

Почему в самописном приёмнике данные не принимаются без Serial.print()?

Писал код в arduino ide под RP2040(планировался оптический приёмник в связке с с передатчиком Arduino nano на Atmega168p, но пока что увяз на самом процессе передачи). В чем суть возникшей проблемы:

1. Система использует код Хэмминга(8,4) (никакой практической пользы в нём нет в данных условиях, просто спортивный интерес), и во время тестовых передач без его использования всё работает прекрасно
2. Тут уже интереснее проблема, точнее первая вытекает отсюда, по абсолютно неизвестной мне причине декодирование кода Хэмминга происходит неверно(да и приём байт в целом), если в цикле заполнения буфера отсутствует вывод serial.
Конечно можно оставить всё как есть, ведь вроде как работает, но мне интересно почему прекращается адекватный приём в отсутствии связи с компом.

Ниже приведу скетчи
Приёмник
#include <Arduino.h>




#define RECEIVEPIN 26

#define DIGRECEIVERPIN 11

#define THRESHHOLD 3320

#define BITRATE 400

#define BITPERIOD 1000/BITRATE

#define THFOBITPERIOD BITPERIOD*0.75

#define GET_BYTE(val, n) (((val) >> (8 * (n))) & 0xFF)




#define TEST




uint32_t _time;

uint32_t prevtime;




uint32_t fullTime = 0;       // 32-битное полное время

uint16_t lastTime16 = 0;     // последнее полученное 16-битное значение

bool firstPacket = true;     // флаг первого пакета




uint32_t FullTime(uint16_t currentTime16) {

    if (firstPacket) {

        fullTime = currentTime16;

        lastTime16 = currentTime16;

        firstPacket = false;

        return fullTime;

    }

    int16_t diff = currentTime16 - lastTime16;

    if (diff < 0) {

        diff += 65536;

    }

    fullTime += diff;

    lastTime16 = currentTime16;

    

    return fullTime;

}




void mig() {

  for(int i = 0; i < 10; ++i) {

    digitalWrite(LED_BUILTIN, HIGH);

    delay(200);

    digitalWrite(LED_BUILTIN, LOW);

    delay(200);

  }

}




void setup() 

{

  pinMode(DIGRECEIVERPIN,INPUT);




  _time = 0;prevtime = 0;




  Serial.begin(115200);

  mig();

  Serial.print(F("Receiver start work"));

  while(digitalRead(11)!=1){}

  delayMicroseconds(THFOBITPERIOD*1000);

}




void loop() 

{

        preambleSearch();

        uint8_t buffer[20];

        for(int i = 0;i<10;++i)

        {

          uint8_t byte1 = receiveByte();uint8_t byte2 = receiveByte();

          buffer[i*2] = byte1; buffer[i*2+1] = byte2; 

          //delay(200);

         Serial.print(byte1,HEX); Serial.print(' '); Serial.print(byte2,HEX);Serial.print(' ');

        }

        Serial.println();

        bool firstByte = decode(buffer[16],buffer[17]) == 0xAA;

        bool secondByte = decode(buffer[18],buffer[19]) == 0x55;

        if(firstByte && secondByte)

        {

        uint8_t bufferr[8];

        for(int i = 0;i<8;++i)

          bufferr[i]=decode(buffer[i*2],buffer[i*2+1]);

        uint16_t data[4];

        for(int i = 0;i<4;++i)

          data[i] = (bufferr[i*2]<<8)|bufferr[i*2+1];

        

        Serial.print(F("Transmitter time work: "));

        Serial.print(FullTime(data[0])/1000);

        Serial.print(F(" T = ")); 

        Serial.print(data[1]*0.01);

        Serial.print(F(" P = "));

        Serial.print(data[2]+90000);

        Serial.print(F(" H = "));

        Serial.print(data[3]);

        Serial.print('\n');}

}




bool preambleSearch()

{

  uint16_t preamble = 0;

  uint32_t bitbuffer = 0;

  while(digitalRead(11)!=1){}

  delayMicroseconds(THFOBITPERIOD*1000);

  while (preamble != 0x4845)

  {

    bitbuffer = (bitbuffer<<1)|digitalRead(DIGRECEIVERPIN);

    preamble = (decode(GET_BYTE(bitbuffer,3),GET_BYTE(bitbuffer,2))<<8)|decode(GET_BYTE(bitbuffer,1),GET_BYTE(bitbuffer,0));

    delayMicroseconds(BITPERIOD*1000);

  }

  return true;

}



uint8_t receiveByte()

{

  uint8_t byte = 0;

  for(int i = 0;i < 8;++i)

    {

      byte = (byte << 1) | digitalRead(DIGRECEIVERPIN);

      delayMicroseconds(BITPERIOD*1000);

    } 

  return byte;

}



uint8_t decode(uint8_t byte1, uint8_t byte2) 

{

  return ((decodeHamming(byte1) << 4) | decodeHamming(byte2));

}

uint8_t decodeHamming(uint8_t sembyte) {

    uint8_t d0 = (sembyte >> 7) & 1; 

    uint8_t d1 = (sembyte >> 6) & 1; 

    uint8_t d2 = (sembyte >> 5) & 1;

    uint8_t d3 = (sembyte >> 4) & 1; 

    uint8_t p0 = (sembyte >> 3) & 1;

    uint8_t p1 = (sembyte >> 2) & 1; 

    uint8_t p2 = (sembyte >> 1) & 1;

    uint8_t parity = sembyte & 1;

    uint8_t syn0 = d0 ^ d1 ^ d2 ^ p0;  // syn1[0]

    uint8_t syn1 = d1 ^ d2 ^ d3 ^ p1;  // syn1[1]

    uint8_t syn2 = d0 ^ d1 ^ d3 ^ p2;  // syn1[2]

    uint8_t error_pos = (syn0 << 2) | (syn1 << 1) | syn2;

    if (error_pos != 0) {

        uint8_t bit_to_flip = 8 - error_pos;

        switch (bit_to_flip) {

            case 7: d0 ^= 1; break;  // bit 7

            case 6: d1 ^= 1; break;  // bit 6

            case 5: d2 ^= 1; break;  // bit 5

            case 4: d3 ^= 1; break;  // bit 4

            case 3: p0 ^= 1; break;  // bit 3

            case 2: p1 ^= 1; break;  // bit 2

            case 1: p2 ^= 1; break;  // bit 1

            case 0: parity ^= 1; break; // bit 0

        }

    }

    uint8_t decSemByte = (d0 << 3) | (d1 << 2) | (d2 << 1) | d3;

    return decSemByte;

}


Передатчик
#include <GyverBME280.h>

#include <math.h>


#define LASER_PIN 9

#define MAXPACKETSIZE 25

#define BITRATE 400

#define BITPERIOD 1000/BITRATE

#define BITBLOCKSIZE BITRATE

#define BMEADRESS 0x76

#define PREAMBLE 0x4845

#define POSTAMBLE 0xAA55

#define CONSTANT 29.254

#define BAR 101325




#define TEST




GyverBME280 dataMaker;


uint16_t packet[6];


uint8_t HammingEncode(uint8_t sembyte);

void sendBlock(uint8_t *block);


const size_t SerialPrintf (const char *szFormat, ...) 

{

    va_list argptr;

    va_start(argptr, szFormat);

    char *szBuffer = 0;

    const size_t nBufferLength = vsnprintf(szBuffer, 0, szFormat, argptr) + 1;

    if (nBufferLength == 1) return 0;

    szBuffer = (char *) malloc(nBufferLength);

    if (! szBuffer) return - nBufferLength;

    vsnprintf(szBuffer, nBufferLength, szFormat, argptr);

    Serial.print(szBuffer);

    free(szBuffer);

    return nBufferLength - 1;

}




void setup() 

{

  Serial.begin(9600);

  pinMode(LASER_PIN,OUTPUT);


  packet[0] = PREAMBLE;

  packet[5] = POSTAMBLE;

  if (!dataMaker.begin(0x76)) Serial.println("Error!");

}




void loop() 

{

      setpacketPayload();

      uint8_t buffer[(MAXPACKETSIZE-1)/2];

      buffer[0] = 0x48;

      buffer[1] = 0x45;

      buffer[((MAXPACKETSIZE-1)/2)-2] = 0xAA;

      buffer[((MAXPACKETSIZE-1)/2)-1] = 0x55;

      for(int i = 1;i<6;++i)

      {

        buffer[i*2] = (packet[i]>>8) & 0xFF;

        buffer[i*2+1] = packet[i] & 0xFF;




      }

      uint8_t encoded_packet[24];

      for(int i = 0;i<12;++i)

      {

        encoded_packet[i*2] = HammingEncode((buffer[i]>>4)&0x0F);

        encoded_packet[i*2+1] = HammingEncode(buffer[i]&0x0F);

      }

      sendBlock(encoded_packet);

      delayMicroseconds(BITPERIOD*1000);

}




void setpacketPayload()

{

  packet[1] = uint16_t(millis());

  packet[2] = uint16_t(dataMaker.readTemperature() * 100);

  packet[3] = uint16_t(dataMaker.readPressure()-90000);

  packet[4] = uint16_t(CONSTANT*(dataMaker.readTemperature()+273)*log(BAR/dataMaker.readPressure()));

}




uint8_t HammingEncode(uint8_t sembyte) 

{

    uint8_t d0 = (sembyte >> 3) & 1;

    uint8_t d1 = (sembyte >> 2) & 1;

    uint8_t d2 = (sembyte >> 1) & 1;

    uint8_t d3 = (sembyte >> 0) & 1;

    uint8_t p0 = d0 ^ d1 ^ d2;

    uint8_t p1 = d1 ^ d2 ^ d3;

    uint8_t p2 = d0 ^ d1 ^ d3;

    uint8_t parity = d0 ^ d1 ^ d2 ^ d3 ^ p0 ^ p1 ^ p2;

    uint8_t byte = 0;

    byte = (byte << 1) | (d0 & 1);

    byte = (byte << 1) | (d1 & 1);

    byte = (byte << 1) | (d2 & 1);

    byte = (byte << 1) | (d3 & 1);

    byte = (byte << 1) | (p0 & 1);

    byte = (byte << 1) | (p1 & 1);

    byte = (byte << 1) | (p2 & 1);

    byte = (byte << 1) | (parity & 1);

    

    return byte;

}




void sendBlock(uint8_t *block)

{

  digitalWrite(LASER_PIN, 1);

  for(int i = 0;i<24;++i)

  {

    sendByte(block[i]);

    Serial.print(block[i],HEX);Serial.print(' ');

  }

  Serial.println();

}




void sendByte(uint8_t byte)

{

  for(int i = 7;i>=0;--i)

  {

    digitalWrite(LASER_PIN, ((byte>>i)&1));  // Сдвиг вправо

    delayMicroseconds(BITPERIOD*1000);

  }

}
  • Вопрос задан
  • 25 просмотров
Подписаться 1 Средний 2 комментария
Помогут разобраться в теме Все курсы
  • PROFIFUTURE
    1С программист
    6 недель
    Далее
  • Нетология
    Инженер по автоматизации
    13 месяцев
    Далее
  • Skillbox
    C++ для робототехников
    1 месяц
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы