Giter Site home page Giter Site logo

Garbage @ 115200 about customsoftwareserial HOT 2 OPEN

ledongthuc avatar ledongthuc commented on July 21, 2024
Garbage @ 115200

from customsoftwareserial.

Comments (2)

xuancong84 avatar xuancong84 commented on July 21, 2024

Yup, I can 100% confirm the bug now.

Today I am testing HLK-LD1155H-24G sensor using Arduino UNO, at Baud rate 115200.
Even after setting parity and stop bit correctly, output is still all garbage.
However, if I connect Port 0 as RX to sensor's TX port (since I only need to input from the sensor and output to PC, i.e., input from PC and output to sensor are not needed), and modify the code to pass-through back to the same Serial port as below:

//#include <CustomSoftwareSerial.h>

//CustomSoftwareSerial Serial1(10, 11);

void setup() {
  Serial.begin(115200, SERIAL_8N1);
  //Serial1.begin(115200, CSERIAL_8N1);
  Serial.println("Custom software serial passthrough started on Port 10 and 11");
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial PIN 0
    Serial.write(Serial.read());   // read it and send it out Serial PIN 1
  }
  
//  if (Serial.available()) {      // If anything comes in Serial PIN 0 (PC USB)
//    Serial1.write(Serial.read());   // read it and send it out Serial1 PIN 11
//  }

//  if (Serial1.available()) {     // If anything comes in Serial1 PIN 10
//    Serial.write(Serial1.read());   // read it and send it out Serial PIN 1 (PC USB)
//  }
}

, I get correct output which means that the built-in Serial is working at 115200 baud rate, but not the CustomSoftwareSerial.

from customsoftwareserial.

xuancong84 avatar xuancong84 commented on July 21, 2024

I have successfully figured out how to read UART at 115200 baud rate for CSERIAL_8N1 on Arduino UNO, other configurations like 8N2/8E1/8O1/etc should similarly apply.

The main difficulty is that since 16000000/115200=138.889, you need to read the RX pin every ~139 clock cycles which is not a lot. Every call to digitalRead() takes about 64 clock cycles, so you cannot think about it. And there is too little time to check for how many data bits, stop bits, or parity bit in different configurations. In addition, you need to be clear about how much time every line of code will take, and function calls must be avoided as much as possible because stack pushing/popping takes many clock cycles.

#define RX_PIN 3
#define TX_PIN 2
#define MAX_BUF 256
#define readPIN (PIND&8?1:0)
#define CYCLES_PER_BIT 139
#define GRACE_CYCLES 40

int RX_head = 0, RX_tail = 0;
char x, RX_BUF[MAX_BUF];
uint16_t RX_packet = 0;
uint16_t next_tick = CYCLES_PER_BIT-GRACE_CYCLES;

void wait_for_nodata(){ // when not sending data, RX PIN is hold high
  TCNT1 = 0;
  while(TCNT1< CYCLES_PER_BIT*10)
    if(!readPIN)TCNT1=0;
}

void uart_start_vect(){
  cli();  // clock-cycle critical session, must disable all interrupts
  TCNT1 = 0;  // reset counter
  while(TCNT1<next_tick);  // wait for the start bit to finish

  // start reading packet
re:
  while(1){
    RX_packet |= (readPIN<<x);
    if(++x>8)break;
    next_tick += CYCLES_PER_BIT;
    while(TCNT1<next_tick);
  }

  // save the byte into circular buffer
  RX_BUF[RX_head] = RX_packet;
  if(++RX_head>=MAX_BUF)
    RX_head = 0;

  // 16000000/115200=138.888 that is 139 for 8/9 of the time and 1/9 of the time
  next_tick += CYCLES_PER_BIT-1;
  RX_packet = 0;
  x = 0;
  while(TCNT1<next_tick); // wait for stop bit to finish
  if(!readPIN){ // another start bit => consective packet
    next_tick += CYCLES_PER_BIT;
    while(TCNT1<next_tick); // wait for start bit to finish
    goto re;
  }

  // prepare for the next
  next_tick = CYCLES_PER_BIT-GRACE_CYCLES;
  
  sei();  // resume all interrupts
}

void setup() {
  delay(200); // prevent running twice when uploading while console is open
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(RX_PIN, INPUT_PULLUP);
  pinMode(TX_PIN, INPUT_PULLUP);
  
  // setup serial
  digitalWrite(LED_BUILTIN, 1);
  Serial.begin(115200);
  Serial.println("TimerSoftwareSerial started:");

  // setup timer1 in normal mode for gettickcount()
  cli();
  TCCR1A = 0;
  TCCR1B = 1;
  OCR1A = 0xffff;

  // setup external interrupt
  attachInterrupt(digitalPinToInterrupt(RX_PIN), uart_start_vect, FALLING);

  wait_for_nodata();

  // start all interrupts
  sei();
}

bool pool(){
  return RX_head!=RX_tail;
}

char *recv(char*buf){
  int p=0;
  while(RX_head!=RX_tail){
    buf[p++] = RX_BUF[RX_tail++]&0b01111111;
    if(RX_tail>=MAX_BUF)
      RX_tail=0;
    if(p>=MAX_BUF)
      Serial.println("\nrecv: buffer overflow");
  }
  buf[p] = 0;
  return buf;
}

char arr[2*256];
void print_bits(char *buf){
  int posi=0;
  char ch;
  for(unsigned char x=0; buf[x]!=0; ++x){
    ch = buf[x];
    for(unsigned char y=0; y<8; ++y)
      arr[posi++] = ((ch<<y)&0b10000000)?'1':'0';
    arr[posi++] = ' ';
    if(posi>100)break;
  }
  arr[posi]=0;
  Serial.println(arr);
}

char buf[MAX_BUF];
void loop() {
  // put your main code here, to run repeatedly:
  if(pool()){
    recv(buf);
    Serial.println(buf);
    print_bits(buf);
  }
}

The above code is tested working on reading UART data from HLK-LD1155H-24G sensor, the idea is to use Timer1 counter to wait until the arrival of the next bit, avoid calling functions and try to use constants instead of variables.

from customsoftwareserial.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.