Thank you Patryk_F for testing and commenting.
I have examined the used library Physicaloid and I found an inconsistency between transfer timeout, hw buffer and baud rates for all chips/adapters. This could affect write of of blocks with more than 64-640 bytes depending on the hw chip.
I also adjusted the AI internal read buffer to 1024B, the same as in the different drivers. This may also bee the practical max size and makes the setting of BufferSize redundant.
To make the logic for read transfers in AI cleaner (as you suggested), I included the function BytesToRead() which returns the number of bytes in the driver read buffer. Returns 0 if no bytes to read.
The new version is now available at https://github.com/rkl099/Appinventor_SerialOTG_Byte
Note: write function is executing in the same thread as AI and blocks other activities, including read in a function called by the timer, until all bytes have been sent from the adapter.
Thank you Patryk_F for testing and commenting.
I start testing. Thanks for the extension.
Hi @rkl099, your extension works very well on an Arduino with CH340, I am going to write a new topic about my experience with your great extension.
And the best part is that by modifying the Mnifest file, you can make the application start automatically when you connect a usb device.
Is it possible to return the name of the USB device to the application? E.g. CP2102 or CH341, maybe even pid and vid?
Awesome extension!!! Thank you very much @rkl099
@rkl099 here my experience with your extension:
I have just updated SerialOTG with a new function Serial.ReadLn() to receive a message terminated with a new_line char. The function returns an empty string, until a complete message is received. This together with SerialPrint() makes ascii message communication simpler to implement.
The extension with some examples can be found at:
It’s time to finalize my extension SerialOTG
First an error in naming and description. WriteSerialHexList and ReadSerialHexList are actual WriteSerialByteList and ReadSerialByteList.
I have added a function Flush to clear the read buffer.
I would like to change the naming of the functions (from Arduino and C) and to remove “Serial” from the names. It only makes the names longer without adding clarity, and “Serial.” is normally included in the extension name.
Function names, all preceded by “SerialOTGn.”
To write and read UTF-8 strings: Write(), Read().
To write and read hex-coded strings: WriteHex(), ReadHex().
To write and read messages in strings: WriteLn(), ReadLn().
To write and read single byte: WriteByte(), ReadByte().
To write and read multiple bytes in list: WriteBytes(), ReadBytes().
Initialize(), Open(), Close(), Flush()
I know that this will cause some trouble, but maybe better now than later.
Do you miss any function?
Waiting for your response
Happy new year from rkl099
Maybe you would add a reading of a certain number of bytes? As it is in the BT component. Read / Write 2Bytes, 4Bytes. Maybe it would also be possible to return the name of the device connected to the usb?
Is this what you need?
if n=0, return all bytes in buffer
if n>0, return all bytes up to n bytes. Actual number of bytes received is given by the list length.
Ps, I saw your reply when I accidentally posted my entry in the wrong thread. You are really fast to reply!
I am using it in my application. If I want to receive 2 bytes, I receive byte by byte in the loop. My device sends messages of different lengths. First, it sends the message length encoded in, for example, 2 bytes. Then he sends the message. Then I know how long the message should be and I know when the message is damaged. I know I can do it in blocks, but I think the extension would be faster.
And so off topic. Thank you for a good extension, fully working, which will worthily replace the built-in component.
I have to study this problem a little. Your application sounds like implementing Modbus, where I must collect a number of bytes without blocking other activities. The end of the message is when there is no more bytes received for x character time. For this I need multithreading and a delay function and I don’t know if this is available in Appinventor.
The alternative is an event driven solution where each character is timestamped.
No, it doesn't require such complicated operations. I read long data using the clock. I think the "n bytes" function is even too much. It would be enough "2 bytes", "4 bytes". "n bytes" would actually introduce complexity if someone entered a large number of .
I had a look at the driver:
Name of device: What is directly available from the library is the driver name like ”com.physicaloid_ai.lib.usb.driver.UartWinCH34x”. This can easily be added to the extension.
For performance: try the function that returns all available bytes in a list. I accidentally gave it the name ReadSerialHexList() (will be renamed). Also next version will be compiled as release with debug logging inhibited.
When we initiate a serial connection in the application, android asks for permission. The content of the permit includes the name of the device, eg "Bridge USB to UART CP2102". I thought this name could be returned.
From what I can see it’s hidden inside the library now. The solution to this has to wait until later.
For example, the USB Terminal application which also uses this driver has the function of displaying the device name.
@rkl099 Just circling back to this. Please let me know if you'd be interested in offering this as an improvement over the existing Serial component.
I will be glad to contribute to Appinventor. I will soon contact you about the best way to integrate the new library and serial component.