Communication with moisture meter from arduino using USB Host Shield

Hi there,

Im working on a moisture meter that has RS232 output and PL2303 to USB cable on.

I can read 0x10 from and send 0x20 to the meter to get the measurement data on Python from PC.

But with Arduino and the shield, i cant send 0x20 to meter. No HEX data response because rcode from SndData function gives zero

Below is the code:

/* Arduino terminal for PL2303 USB to serial converter and DealeXtreme GPRS modem. */
/* USB support */
#include <usbhub.h>

/* CDC support */
#include <cdcacm.h>

#include <cdcprolific.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude#include <spi4teensy3.h>

#endif#include <SPI.h>

class PLAsyncOper: public CDCAsyncOper {
  public: uint8_t OnInit(ACM * pacm);
};

uint8_t PLAsyncOper::OnInit(ACM * pacm) {
  uint8_t rcode;

  // Set DTR = 1
  rcode = pacm -> SetControlLineState(1);

  if (rcode) {
    ErrorMessage < uint8_t > (PSTR("SetControlLineState"), rcode);
    return rcode;
  }

  LINE_CODING lc;
  lc.dwDTERate = 2400;
  lc.bCharFormat = 0;
  lc.bParityType = 0;
  lc.bDataBits = 8;

  rcode = pacm -> SetLineCoding( & lc);

  if (rcode)
    ErrorMessage < uint8_t > (PSTR("SetLineCoding"), rcode);

  return rcode;
}
USB Usb;
//USBHub     Hub(&Usb);
PLAsyncOper AsyncOper;
PL2303 Pl( & Usb, & AsyncOper);

void setup() {
  Serial.begin(2400);
  #if!defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  #endif
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSCOKIRQ failed to assert");

  delay(200);
}

void loop() {
  Usb.Task();

  if (Usb.getUsbTaskState() == USB_STATE_RUNNING) {
    uint8_t rcode;

    /* reading the converter */
    /* buffer size must be greater or equal to max.packet size */
    /* it it set to 64 (largest possible max.packet size) here, can be tuned down
    for particular endpoint */
    uint8_t buf[64];
    uint16_t rcvd = 64;

    rcode = Pl.RcvData( & rcvd, buf);
    if (rcode && rcode != hrNAK)
      ErrorMessage < uint8_t > (PSTR("Ret"), rcode);

      if (rcvd) { //more than zero bytes received
        for (uint16_t i = 0; i < 64; i++) {
            Serial.print(buf[i], HEX);
            Serial.print(" ");
        }

        if (rcvd == 1) {
          Serial.println("Size = 1");
          Serial.print("HEX from device: ");
          Serial.println(buf[0], HEX);
          //Confirm if we got 0x10 response from device
          if (buf[0] == 0x10) {
            Serial.println("Got data ready to send response from device ");
            //Send 0x20 to device
            uint8_t rq = 0x20;
            rcode = Pl.SndData(1, &rq);
            
            if (rcode) {
                ErrorMessage < uint8_t > (PSTR("SndData"), rcode);
                Serial.print("HEX from user: ");
                Serial.println(rcode, HEX);
            }
          }
        } else {
          Serial.println("Size > 1");
          Serial.println(sizeof(buf));
          for (uint16_t i = 0; i < rcvd; i++) {
            Serial.print(buf[i], HEX);
            Serial.print(" ");
          }
        }
      }
  }
}

Please help for the error in my source, i think SndData function i wrote not correct
Thank you.

Hi @hoahoctro

welcome to the arduino-forum.

well done posting your code as a code-section in the first posting.

I understand this

what I do not understand is this

If your moisture-meter has a RS232-interface why do you need USB???

Help us to help you.
You will have to provide much more detail information about your project.

  • post a link to the manual of your moisture meter
  • post a link to the USB-shield
  • post the python-code that works

post a smartphone-picture of a hand-drawn schematic how you connected everything together.

additionally: english seems not to be your native language. What you have written so far is at the border to be understandable. In arduino-projects it is very important to write enough details.
Si if you are unable to find the words in english write the text in your native language and let do google-translate the translation.

best regards Stefan

The meter has RS232 output as 3.5mm female and a PL2303 USB cable to connect to their software

My need is connect this cable to USB Host Shield to make communication between it and Arduino board as picture, the Arduino then gets 0x10 from meter (sent whenever a measurement is done) and sends 0x20 to gets measurement data (10 bytes HEX)

The python script that works well

import serial

ser = serial.Serial('COM17', 2400)

# Check if serial is available then print what is read
if ser.isOpen():
    print(ser.name + ' is open...')
    # Make the handshake Xon/Xoff
    #ser.write(b'\x11')
    # Make the handshake RTS/CTS
    #ser.setRTS(True)
    # Setup flow control to RTS/CTS
    #ser.setRTS(True)
    while True:
        # Read bytes from serial
        data = ser.read()
        # Print what is read
        print(data.hex)
        # Check if we get 0x10
        if data == b'\x10':
            # Send 0x20
            ser.write(b'\x20')
            # Send 0x20 as uint8
            #ser.write(bytes([0x20]))
            # Send 32 as uint8
            #ser.write(bytes([32]))
            # Then check if we got data, if so print it
            #data = ser.read()
            #print(data)
            if ser.in_waiting > 0:
            #    print(ser.read())
                # Convert to hex
            #    print(ser.read().hex())
                print("Got data")
            else:
                print("No data")
    else:
        print('serial not available')

In the arduino source code, nothing wrong with getting 0x10, but i dont know why the line

//Send 0x20 to device
            uint8_t rq = 0x20;
            rcode = Pl.SndData(1, &rq);

never works, rcode gives zero, so the meter doesnt response with measurement data

If you use a RS232-to-TTL-converter you will not need the USB-shield.

You would solder an adapter-cable 3,5mm-male-plug
to
D-SUB-male-plug
and then you can connect the meter over this adpater to your arduino directly
The RS232-to-USB-converter becomes obsolete.

If you want to keep the USB-shield you will have to provide the manual of your USB-shield
At least where did you buy the USB-shield?

Post a link to the example-codes that were delivered with the USB-shield.

Again: all this hassling is gone if you use a RS232 to TTL-converter.
Then everything will be simple as connecting two arduinos directly over two IO-pins

best regards Stefan

I use this USB Host Shield 2.0 https://github.com/felis/USB_Host_Shield_2.0

The example code is in examples/pl2303/pl2303-gprs-terminal https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/pl2303/pl2303_gprs_terminal

The context doesnt give me more choices, so i tried this way first, i think i implemented SndData function not correctly, but still dont understand more

The links that you provided point to github.
Github did not produce the USB-shield.
Where did you buy your USB-shield?

It might be that this shield uses a different chip than the Github-code expects.
If the "bug" is a different chip then you could search for decades in this code without solving the problem.

If you have plugged in the RS232-to-USB-adapter into your PC
post a picture of what the device-manager shows about this adapter.

Hello hoahoctro

Welcome to the worldbest Arduino forum ever.

Make a pure USB integration test sketch without any other libaries.

Have a nice day and enjoy coding in C++.

https://hshop.vn/products/arduino-usb-host-shield

The chip still be MAX342E, so i dont think any problem with the chip

I'm not familiar with USB-host-shields this line of code

  lc.dwDTERate = 2400;

seems to define the baudrate of the USB-client (your RS232-to-USB-adapter)
this line defines the baudrate of the arduino's standard serial interface

Serial.begin(2400);

did you change the IDE-serial monitor to 2400 baud?

again:

The reason is:
You have not followed the general advice giving in the sticky thread "how to get the best out of this forum" which says
"post all the detail informations about your knowledge-level in programming and in electronics.

So the other users simply don't know what your knowledge-level is.
To make sure that all details are correct you were asked several details and if you want to have effective help you should answer all these questions.

Otherwise the answers will become a more and more general advice character that are just a diplomatic way to say "if you don't provide sufficient information here are links to lern yourself"

Yes i did it from beginning

Profiolic PL2303 as shown

the device-mnager says prolific (not PL2303).
It is very likely that using the PL2303-library will work. Maybe you can get some additional information in the driver-details on your PC.

What does the manual of your moisture-meter say about how the communication works?
Is inside the moisture-manual a description what the PC must send towards the meter and what the meter will respond?

compared to the code on Github
what was the reason to modify this line of code?

your code

    rcode = Pl.RcvData( & rcvd, buf);
    if (rcode && rcode != hrNAK)
      ErrorMessage < uint8_t > (PSTR("Ret"), rcode);

original on Github

         rcode = Pl.SndData(1, &data);
         if (rcode)
            ErrorMessage<uint8_t>(PSTR("SndData"), rcode);

You are checking for receiving a single byte here

        if (rcvd == 1) { // checking for a single byte
          Serial.println("Size = 1");
          Serial.print("HEX from device: ");
          Serial.println(buf[0], HEX);
          //Confirm if we got 0x10 response from device
          if (buf[0] == 0x10) {
            Serial.println("Got data ready to send response from device ");

it might well be that a line-ending character is send then you have more than one character and variable rcvd has a value greater than 1

For analysing such bugs it is always a good idea to print to the serial monitor what is going on in the code. You have to analyse what the values of variables are
In this case this means to print the value of variable rcvd here

      if (rcvd) { //more than zero bytes received
        serial.print("rcvd=");
        serial.println(rcvd);

        for (uint16_t i = 0; i < 64; i++) {
            Serial.print("buf[");
            Serial.print(i);
            Serial.print("]=");
            Serial.print(buf[i], HEX);
            Serial.print("  ");
        }

and then post as a code-section what you get printed to the serial monitor

The code on Github does send data here

void loop()
{
    Usb.Task();

    if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
    {
       uint8_t rcode;

       /* reading the keyboard */
       if(Serial.available()) {
         uint8_t data= Serial.read();

         /* sending to the phone */
         rcode = Pl.SndData(1, &data); // <= <= <= <= <= <= SENDING data
         if (rcode)
            ErrorMessage<uint8_t>(PSTR("SndData"), rcode);

your code does not send anything

void loop() 
{
  Usb.Task();

  if (Usb.getUsbTaskState() == USB_STATE_RUNNING) 
  {
    uint8_t rcode;

    /* reading the converter */
    /* buffer size must be greater or equal to max.packet size */
    /* it it set to 64 (largest possible max.packet size) here, can be tuned down
    for particular endpoint */
    uint8_t buf[64];
    uint16_t rcvd = 64;

    rcode = Pl.RcvData( & rcvd, buf);
    if (rcode && rcode != hrNAK)
      ErrorMessage < uint8_t > (PSTR("Ret"), rcode);

      if (rcvd) { //more than zero bytes received

you haven't provided the manual of your moisture-meter
all information about the communication-process between moisture-meter and data-receiver (beeing a PC or your arduino)
are these poor sentences

what does that exactly mean?
especcialy writing

why do you expect the send-function to give a non-zero value when everything is about receiving???

Which device is initiating the data-sending? moisture-meter or partner of moisture-meter?
again through the lack of detailed information I have to speculate about possabilities instead of you providing detailed information:

Does the moisture-meter send the 0x10 automatically? If yes at what time-intervals?
If it does not send it automatically does the data-receiver have to initiate the sending?
is the data-sending initiated by a button-press?

Do you have an oscilliscope or a logic analyser that you could use the analyse and display what bit-banging is happening on 3,5mm plug?

There is no document, i just found a equivalent one of another meter from https://sigrok.org/wiki/Colead_SL-5868P

When the meter get measurement data, it sends 0x10 to PC

When PC receives this, it responses with 0x20 to meter

The meter then send 10 bytes HEX data to PC

Look like this:
image

They re same array with same values

buf[0]=10  buf[1]=1  buf[2]=0  buf[3]=2  buf[4]=0  buf[5]=0  buf[6]=0  buf[7]=40  buf[8]=7B  buf[9]=6  buf[10]=3  buf[11]=23  buf[12]=0  buf[13]=3  buf[14]=1  buf[15]=2  buf[16]=0  buf[17]=1  buf[18]=E4  buf[19]=9E  buf[20]=A9  buf[21]=3A  buf[22]=C6  buf[23]=BE  buf[24]=C3  buf[25]=3D  buf[26]=4D  buf[27]=7F  buf[28]=5F  buf[29]=FD  buf[30]=92  buf[31]=FF  buf[32]=E7  buf[33]=D0  buf[34]=F5  buf[35]=FF  buf[36]=2F  buf[37]=3E  buf[38]=7F  buf[39]=93  buf[40]=ED  buf[41]=7B  buf[42]=BC  buf[43]=E6  buf[44]=9  buf[45]=BD  buf[46]=FC  buf[47]=7  buf[48]=A2  buf[49]=51  buf[50]=2A  buf[51]=DE  buf[52]=C2  buf[53]=D9  buf[54]=86  buf[55]=DD  buf[56]=B9  buf[57]=6F  buf[58]=BE  buf[59]=AA  buf[60]=3A  buf[61]=99  buf[62]=22  buf[63]=4D  

this part is receiving, confirm if we get 0x10, then we send 0x20

what makes you sure that a
Colead SL5868P sound-meter
works with exactly the same protocol as your MC-7825PS moisture-meter?

as a last appell
either you post more detailed information or I give up
from where does this data come from?
image

which devices are connected to each other
what is the meaning of the "10" in front of the "20"
does this table contain send and receive data?
The meter sends a "10" and then the pc sends a "20" then the meter responds with data

what does it mean if you write

in the receive-buffer you have the same values as where??
And what do these values represent? How do you interpret these values?

lasz chance: if you are unable to provide

DETAILED

information
that

clearly and explicitly specifies sender and receiver and interpretation of each and every single byte

I will mute this thread and you as a user

what i have told you is all information i get after research this meter, i dont know more

I use Advanced Serial Monitor Port to spy the serial data between meter and pc software

It seems you are asking continuously more than i can provide, so we stop here.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.