For the built-in component, the WriteSerial method takes a string and expects that it's going to write to a device that understands strings. It would be straightforward enough to provide a second method that takes bytes instead of strings for the purposes of transmitting binary data over the serial port.
I understand that the author of the extension would have to do a little sign-to-number converter? I also read somewhere that appinventor plans to introduce variable declarations?
Would it be possible to make an additional block that would convert char to int? It would be enough to subtract 48 from char, I think.
Can't you do that with existing blocks ?
Not because the result will be sent as char anyway. This must be done outside of appinventor. I have tried in different ways.
I think it works like this now:
In blocks I want to send the number 11 to the USB -> appinventor passes the variable 49 49 to the extension
After receiving 49 49, you would have to subtract 48 from each byte to have 11 and send this variable to usb as one byte.
Again, the appropriate thing would be to provide a new function. I do think @ABG has an example of using the WebViewer to convert arbitrary values to their ASCII values to strings to workaround limitations in components that expect a string rather than bytes. You may want to look in the FAQ sections to see if there's a workaround you can use until someone implements something for your use case.
So if you want to send the value 0 you would have to send the NULL character? I understand well? I used to look for a utf converter, all I found was an idea with my own character and value array and so I solved it in my program, but I don't have "invisible" characters in the array. If there is another solution for utf conversion, I would like to read about it, it would probably save me a lot of blocks.
Here's the Math FAQ with conversions
Now I have added some functions to SerialOTG.aix to read and write bytes of any value 0.255 on the serial line. You can read/write a byte as a number 0..255 (00..FF) or as a hex-coded string 2*hexChar for each byte on the serial line. It is no problem with UTF-8 code, as we only use char 0..9 and A..F in the string data.
For evaluation, but I think it adds unnecessary complexity to the extension:
Functions to read/write hex-coded strings in a list. Each element corresponds to a byte on the serial line.
Upload of hex file to Arduino.
This updated extension can be found at:
I have included a test program SerielOTG_Byte that demonstrates the use of the new functions. Please return with comments on the extension.
I understand from some of the discussions that users expects some kind of package handling of the serial line data, but it is just a serial connection with a stream of bytes. This can be confusing. You have to add the formatting of the messages yourself, by timing and/or by the content. When you write bytes, you can expect that all are transmitted within a time depending on the baud rate. When you read bytes, you just gets the number of bytes that has been received from last read, up to now.
I can now connect to my device from the test application. The new features will be useful for sure. I will be able to say more when I implement usb in my application :). The extension is super easy to run, I hope it will replace the built-in extension. Thank you.
Is there any way to check if data is available in the buffor so as not to flush the buffor when checking? Kind of like "ByteAvalibleToReceive" in a BT component.
I am not sure that this function will be useful. You have to take care of every incoming byte anyway (see above on packet handling).
The com.pavitra.5.aix extension has a callback function, but from what I can see in the source code, the callback is only a function of a call to the read function. For me it is only a more complicated way of read, without adding functionality.
The library itself has a callback function for incoming bytes, but I have not tested it. I guess it is possible to add it to the extension.
It is also possible to add a test if there are any bytes in the library read buffer, but this new function needs some new code in the library and a lot of testing. It will take some time to implement.
I implemented USB Serial in my application. I have a few problems reading and writing long HEX lists. When trying to send a long list I get error 3902. I made such a layout for testing. I connected the CP2102 adapter to the phone and the BT XM-15B module to the adapter. On the laptop, I launched the terminal and connected to the BT module wirelessly. I used your test app for the test. Baudrate 9600, set to List and Hex. I want to send about 3000 Bytes separated by spaces. When trying to send, I am getting error 3902 and the serial port monitor on my laptop only received 640 Bytes. A fixed 640 Bytes are received each time. What is the Buffer in the extension for? Because changing its value doesn't improve anything either.
When reading these 3000 Bytes it is ok at Baudrate 9600, while at higher speeds it loses a lot of bytes. But here it seems to me that the problem is android because I had a similar situation when connecting BT with higher speeds than 9600.
I can only say for the moment:
CP2102 chip internal write buffer 640B, read buffer 576B
Driver internal read ring buffer 1024B
I don’t know (yet) why the data is not divided in 640B pieces!
The buffer size in the extension is the max nr of bytes from the driver ring buffer for each read()
When I use the CP2102 adapter between my laptop and my device, I send 3000 bytes to my device without any problem. So maybe not the adapter is the problem, but the cdc driver. I will also do a test in the USB Terminal which also uses these resources as your extension. A friend of mine has implemented WebUSB on his website and also with this website I can write 3000 Bytes to my device with CP2102.
Ok, I tested the android USB terminal. About 1920 Bytes can be sent from the USB terminal to the laptop and the application disconnects. On the laptop terminal you can see that the data is received in smaller batches, so it is possible that the USB terminal is sharing the data. I will play and see if it is possible to send by dividing the data into smaller lists and send them with the clock speed.
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.
I start testing. Thanks for the extension.