Go Down

Topic: ESP8266 Connect to Serial module (Read 120 times) previous topic - next topic

khaf_0

Hello,
i buy a decibel sound level meter module , from here
module communication is Serial (TX , RX),
i wana connect this module to esp8266(NodeMCU),
questions:
1-should i connect tx rx pins on module to rx tx pin on esp8266?
2-i use SoftwareSerial.h library and i cant get correct response.

any one can help me for correct code and connection gpio?
thank you

septillion

#1
Aug 21, 2019, 09:31 am Last Edit: Aug 21, 2019, 09:32 am by septillion
The ESP8266 only has a single Serial which can receive data. You can use it but you will loose serial (and wifi debug) to the PC. You can use SoftwareSerial for the module if that works on an ESP (think it does by now).

And some say ESP pins are 5V tolerant but officially they are not. The module seems to be a 5V one and will probably output 5V on it's serial as well. So a level shifter is recommended.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Deva_Rishi

You can use SoftwareSerial for the module if that works on an ESP (think it does by now).
It does work by now but not reliably at the BAUD-rate of the unit (115200) although you may be getting reasonable results for transmission, reception will falter, so i recommend the hwSerrial.

And some say ESP pins are 5V tolerant but officially they are not. The module seems to be a 5V one and will probably output 5V on it's serial as well. So a level shifter is recommended.
Yes for sure use a level shifter or at least a voltage divider for the SLM tx->rx NodeMCU. The SLM probably responds to the 3.3v logic levels the NodeMCU is sending. (btw the unit appears to work in just 1 way mode as well)

If you want to use Serial for debugging you could connect a USB <-> TTL to the NodeMCU and use swSerial for that at a lower BAUD-rate.
To 'Correct' you have to be Correct. (and not be condescending..)

septillion

Yeah, prefer hardware Serial over Software as well. The ESP is a lot faster than an Uno so the 115200 baud might work out but I have no experience.

If you want to use Serial for debugging you could connect a USB <-> TTL to the NodeMCU and use swSerial for that at a lower BAUD-rate.
Or use Serial1 for that. It's one way but ideal to output debug info.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

khaf_0

no one answer to this question?
i can recived bytes from serialTTL but i cant seperate bytes and i get just data,

Three, serial parameters and instructions

3.1 serial parameters

Serial baud rate: 115200, parity bit: No, stop bit: 1 bits.

3.2 serial data packet protocol

Packet format: start + Command + data + check value. The total length of a frame is 6 bytes.

1) starting symbol: BBAA, 2 byte length (0xBB, 0xAA);

2) command: 1 byte length;

00, return to the module software version number command;

01, return the decibels data command;

3) data: 2 byte length, software version information and decibel value data are stored in some data segments.

4) check value: 1 byte length, initiating symbol, command and data arithmetic and check, not exceeding 256 overflow value.

Four. Communication command description

4.1 module software version number command

Such as: BB AA 00020067

The starting point: BB AA, which represents the beginning of a frame;

Command: 00, indicating that this frame is the frame of the software version number of the return module.

Data: 0200, indicating that the version number of module software is 2;

Check value: 67, arithmetic and check value for BB, AA, 00, 02, 00.

Note: this frame is the first returned packet after the module is powered up and returns only after power on.

4.2 decibels data command

Such as: BB AA 01 7F 02 E7

The starting point: BB AA, which represents the beginning of a frame;

Command: 01, indicating that this frame returns DB values.

Data: 7F 02, which indicates the decibel value is 63.9dB. The low byte is in front, the high byte is in the back, and each unit is 0.1dB;

Check value: E7, arithmetic and check value for BB, AA, 01, 7F, 02.

Note: this frame returns the frame once every 500ms after the module returns the software version number command frame.

Deva_Rishi

no one answer to this question?
i can recived bytes from serialTTL but i cant seperate bytes and i get just data,
Well yes, but your question was about the reception. not about the parsing.
The information is from the link you provided earlier. You are getting the data, in  the 'manua;' this data is represented in HEX-format.
I think the bit format is the same as what the Serial port's default setting is (i think anyway..) if you set the Serial to 115200
Code: [Select]
Serial.begin(115200) you should receive the correct bytes so the you'll receive the header (0xBB followed by 0xAA) so the first byte is 170 and the 187.
Do you data receive thing (check out the Serial communication examples to get some idea on how to do this)

See in point 4.1 & 4.2 how the data is sent. To get the Version nr (if byte nr. 3 == 00) you could convert the next 2 bytes to a string of the hexagonal representation. (only happens at startup i'd skip it and first work on 4.2)
If byte nr.3 == 1 (or 0x01 but that is the same..) read the bytes and put them in a variable like
Code: [Select]
uint16_t vari = byte3 | (uint16_t) byte4 <<8 ; and then divde by 10.0 and store the value in a float
Code: [Select]
float db = vari / 10.0; There is no information about the check value, it may be a standard CRC-check for now i'd focus on finding the header and parse whatever comes after.
To 'Correct' you have to be Correct. (and not be condescending..)

khaf_0

Well yes, but your question was about the reception. not about the parsing.
The information is from the link you provided earlier. You are getting the data, in  the 'manua;' this data is represented in HEX-format.
I think the bit format is the same as what the Serial port's default setting is (i think anyway..) if you set the Serial to 115200
Code: [Select]
Serial.begin(115200) you should receive the correct bytes so the you'll receive the header (0xBB followed by 0xAA) so the first byte is 170 and the 187.
Do you data receive thing (check out the Serial communication examples to get some idea on how to do this)

See in point 4.1 & 4.2 how the data is sent. To get the Version nr (if byte nr. 3 == 00) you could convert the next 2 bytes to a string of the hexagonal representation. (only happens at startup i'd skip it and first work on 4.2)
If byte nr.3 == 1 (or 0x01 but that is the same..) read the bytes and put them in a variable like
Code: [Select]
uint16_t vari = byte3 | (uint16_t) byte4 <<8 ; and then divde by 10.0 and store the value in a float
Code: [Select]
float db = vari / 10.0; There is no information about the check value, it may be a standard CRC-check for now i'd focus on finding the header and parse whatever comes after.

thank you
please check where is error:

#include <SoftwareSerial.h>
#define BAUD_RATE 115200
SoftwareSerial swSer(1, 3);
byte buffer[6];

void setup() {
  swSer.begin(BAUD_RATE);
pinMode(16, OUTPUT);
 
}

void loop() {
 swSer.begin(BAUD_RATE);
  byte index = 0; // Index into array; where to store the character
    delay(500);
   // int light = 0;
  if (swSer.available() > 0) {
    swSer.readBytes(buffer,6);
  uint16_t vari = buffer[3] | (uint16_t) buffer[4] <<8 ;
  float db = vari / 10.0;
   analogWrite(LED_BUILTIN, db * 10 );
  }
}

 


Deva_Rishi

Please use </> code-tags to display your code !
Code: [Select]
#include <SoftwareSerial.h>
#define BAUD_RATE 115200
SoftwareSerial swSer(1, 3);
You are still using Software Serial, not only that but defining the pins used by hardware Serial in reverse. (this means that if you had functionalitybefore you may need to physically swap the pins now)

Code: [Select]
void loop() {
 swSer.begin(BAUD_RATE);
and the call to begin should be in setup() not in loop()

There should be no real need for the delay(500); although the frames get sent 500ms apart we will only read once we receive (a delay(1) for stability may help a bit)

if you always read a full frame you may miss the header and therefore read the wrong bytes as values, so read the bytes one at a time and compare.

GPIO16, the builtin ledpin, is not a PWM pin so it does not respond to analogWrite(). If you want to show the soundlevel that way you have to connect a led (via a resistor) to a PWM pin (GPIO15, GPIO14, GPIO12 or GPIO4. marked on the board as D8, D5, D6 or D2)

Code: [Select]

#define BAUD_RATE 115200
#define ANALOG_PIN 15
byte buffer[6];
void setup() {
  Serial.begin(BAUD_RATE);
  pinMode(16, OUTPUT);  // LED_BUILTIN
  pinMode(ANALOG_PIN,OUTPUT);
}

void loop() {
  byte index = 0; // Index into array; where to store the character
  if  (Serial.available()) { 
    buffer[0] = Serial.read(); // first read the first byte of the header
    delayMicroseconds(10); // although your baudrate is high the chance of not having the second byte in there
                                       // after the first has been read still exists
    if ((buffer[0]==0xAA) && (Serial.available())) {
      buffer[1] = Serial.read();
      delayMicroseconds(60);
      if ((buffer[1]==0xBB) && (Serial.available()>3)) { // we've found the header !
        for (uint8_t i=2; i<6; i++)  buffer[i] = Serial.read();  // read the rest of the Serial-buffer
        if (buffer[2]==0x01) {  // a soundvalue frame       
          uint16_t vari = buffer[3] | (uint16_t) buffer[4] <<8 ;
          float db = vari / 10.0;
          //analogWrite(LED_BUILTIN, db * 10 );  // GPIO16 is not a PWM pin
         
         digitalWrite(LED_BUILTIN,HIGH); // it won't show us the value received but some visual confirmation 
         delay(100);                                // of a correct frame it will (though we haven't done the CRC
         digitalWrite(LED_BUILTIN,LOW);
         
         analogWrite(ANALOG_PIN,(uint8_t) db); //also do not multiply by 10 if you want to use the
                                         // the full range use the map() function
        }
        else if (buffer[2]==0x00) { //  the  version number frame
        }
      }  // 2nd headerbyte
    }   // 1st headerbyte
  }  // Serial.available()
}

this is what i would do for testing (the delay(100) would have to go for the final program and maybe even the delayMicroseconds() ) 
To 'Correct' you have to be Correct. (and not be condescending..)

Go Up