Comments (49)
from usbserial.
There are multiple solutiouns. If you don't have high performance-critical code, you can code something like below. You can check start and stop characters or byte size etc.
private StringBuilder sb = new StringBuilder();
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
@Override
public void onReceivedData(byte[] arg0) {
String data = new String(arg0, StandardCharsets.UTF_8);
sb.append(data);
if (data.endsWith("#") || data.endsWith("#\n")) {
//Do what ever you want
sb.setLength(0);
}
}
};
from usbserial.
Hi,
In some devices data is split into more than callback because of the usb to serial chipset. You can onvercome this using two approaches:
- Append the received data into a buffer and use it when it makes sense.
- Use the sync vdrsion of the library (added in the last version). Methods are called like syncOpen, syncRead, syncWrite...With those methods you should be able to specify how many bytes you want to receive.
from usbserial.
Thank you for your fast reply! I had already been buffering but it was troublesome. I'll see with the sync version.
from usbserial.
It is the last thing I added so it would be nice to receive your feedback about if the sync version works correctly.
What USB-Serial converter does your arduino use?
from usbserial.
I will work on that today and get to you after that.
I am using the last Arduino UNO which uses their own firmware for USB-Serial converter on their Atmega8U2 chip but it should be like a FTDI chip.
from usbserial.
So after doing some tests with the sync version, it seems to be working but I get a lot of 0 in between my bytes when I (sync)read. I suppose that's because i limited my byte array to 13 bytes and i just receive a certain amount below 13. The thing is that I send from the arduino exactly 13 bytes. So I still get a truncated packaged received from the Arduino.
I did a simple test where I write 13 bytes from android every 2 seconds
and on the arduino it sends s13 bytes whenever it receives something (13 bytes).
And everytime android sends something it reads in a while loop (with a timeout) and prints what it received.
in summary :
Android --> Arduino --> Android
.........13 bytes.....13 bytes.........
I will look further to see how I can improve my code.
from usbserial.
Java arrays are set to 0 by default so probably you are receiving less than 13 bytes when the timeout raises.
Are you using UsbSerial 4.1.1 because that release solved an issue with the synchronous read in FTDI devices.
I would check the arduino code too.
from usbserial.
Yes I am using the final release.
So yes i suppose that it was because i was receiving less than what i expected that I had the 0s.
But the biggest problem comes from receiving multiple package when sending only one. And this is the case for both methods (sync and callback).
How would you suggest using the sync version the best way? Having a timeout seems to be the problem. Because the data could arrive at the end of the timeout, so it would cut the received data. And I can't use flow control.
The code on Arduino seemed fine. I went back with the callback version because it was simpler to work with and improved my buffering to get what I want.
But it could be great to have the received data in a whole.
I suppose the only solution is to buffer the received package.
from usbserial.
Set timeout to 0 :)
from usbserial.
OdysseusU, did you get the synchronous api to work? i wanted to attempt using it since I only need to keep reading a string of 13 characters from the Arduino.
from usbserial.
Yes do you have any problem with it? I didn't really have any. The main problem was that my frames were cut but that is device related.
If you want to use synchronous api just put a while in there with a syncRead and changing everything open by syncOpen and close by syncClose. This should be good.
from usbserial.
Seems i do..so i only get one reading and thats it..i put the syncRead in the broadcastReceiver...not in a while loop just in there and then used tvappend to append to display..1st error is decoding ..not converting to string, 2nd error is getting just 1 read and thats it
from usbserial.
The decoding is a bit strange with android. Look into other methods to convert into string (don't use the method .toString()) rather create your String and put your encoding ( new String(bytes, encoding UTF8 for instance). I don't really remember how to catch the string again but I think the .toString() method isn't good.
And the reading problem, are you sure your Arduino sends the data multiple times? Did you put the timeout to 0? this caused me some problem since it waits until the byte arrives and sometimes stops completely the application if nothing is sent (even if it was). Put a short timeout to be sure.
But generally the library works as it was intended to. So the problems you encounter comes from java or your arduino.
from usbserial.
So.i did that and it cuts my string..it produces the string but only a quarter of it...atrange..its still splitting up the data
from usbserial.
Idk why it still splits it up..but it does. I set the size of the array to 14, because the string im expecting is A: 000 B: 000...so idk what to do
from usbserial.
Yup i've got the same problem. Your solutions are :
- Set timeout to 0 (or longer to catch all the bytes) and wait to have all your bytes
- Set a buffer which adds up every bytes you have until you get your 13 bytes.
I took the second solution because i couldn't afford to wait.
This is not library related as every library that does the serial with arduino does the same. It's device related (or Android related, don't know).
from usbserial.
So you really could use the async..but i.noticed i was losiglng data..so you read until you have 13 bytes..what if you receive extra bytes so its the next set of data..
from usbserial.
Well you have to know when to stop the reading and do buffering right. But I never lose the data (only 1 every minute or so when sending every 50 - 100 ms)
But yeah I went with the async version.
from usbserial.
So you do lose a byte every min? Can i see how you did it
from usbserial.
I won't put the whole code here it would be useless since it's quite specific what I do.
But here is a sample in the read callback, b being the bytes received :
`
if(b != null){
if(b.length > 0){
if (isStartByte(b[0])&& !startbytefound) { //look if its a new frame
startbytefound = true;
clearBytes(); // clears my buffer
iNBbyte = /* formula specific to my use, just put the number of bytes you need */;
}
appendBytes(b):
if(bufferSize >= iNBbyte && startbytefound){
bufferSize = iNBbyte;
byte[] buf = new byte[iNBbyte];
System.arraycopy(buffer, 0, buf, 0, bufferSize);
clearBytes();
appendBytes(buf); // append to my buffer
checkData(); //process the data
startbytefound = false;
isAck = false;
}
}
}`
What I do is quite simple.
I check if i have the start data (in your case 'A')
then i begin to append the data in the buffer.
If i have what i need (bufferSize >= iNBbyte) then i process it.
I do all these checks (b.length > 0 or b != null) because sometimes i get empty bytes or bytes of length too short, and even sometimes i get the data 2 times.
from usbserial.
okay i tried something similar to this algorithm. in your arduino code, do you do serial.println..so theres a new line in the string, or just serial.print?
from usbserial.
Actually i use serial.write to write byte code. But you could serial.println and find the ยด\n' character to find the end of frame
from usbserial.
It is actually simpler since you just need to find if your received bytes contains the ยด\n' character and if it does process the buffer you have. But it is more optimized to not search for the ยด/n' character if you already know the size of the frame you should receive.
from usbserial.
So can i just stick to the way you did it with serial.println in arduino?
from usbserial.
Yes the serial.println all it does is serial.print +'\n'
from usbserial.
byte [] data=new byte[0];
byte iNBbyte;
byte[] buffer=new byte[13];
int bufferSize=13;
boolean isAck=false;
public boolean isStartByte(byte firstChar){
if(firstChar=='A'){
return true;
}
else{
return false;
}
}
public void clearBytes(){
data=null;
}
public void appendBytes(byte[] b){
byte[] one=buffer;
byte[] two=b;
byte[] combined=new byte[one.length + two.length];
for(int i=0; i<combined.length; i++){
combined[i]=i<one.length?one[i]: two[i-one.length];
}
buffer=combined;
}
public void checkData(){
tvAppend(errorCheck,buffer.toString());
}
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
@Override
public void onReceivedData(byte[] arg0) {
data = null;
// data = new String(arg0, "UTF-8");
data=arg0;
//try this for now
if(data!= null){
if(data.length > 0){
if (isStartByte(data[0])&& !startbytefound) { //look if its a new frame
startbytefound = true;
clearBytes(); // clears my buffer
iNBbyte =13; /* formula specific to my use, just put the number of bytes you need */;
}
appendBytes(data);
if(bufferSize >= iNBbyte && startbytefound){
bufferSize = iNBbyte;
byte[] buf = new byte[iNBbyte];
System.arraycopy(buffer, 0, buf, 0, bufferSize);
clearBytes();
appendBytes(buf); // append to my buffer
checkData(); //process the data
startbytefound = false;
isAck = false;
}
}
}
what am i doing wrong???
from usbserial.
It's my fault I didn't detailed my variables.
clearBytes() should clear the buffer and not data.
also bufferSize should be the actual bufferSize (which would be buffer.length) and iNBbytes the threshold at which you launch the check data (iNBbytes should be constant in your case at 13).
Also are you sure byte=='A' works? I don't know if it gives the same byte, but that i'm not sure.
And you don't need data as it's only used as a local variable here.
And finally, to copy the array you should use System.arraycopy which is faster and simpler too.
so the code would be :
`
int iNBbyte = 13;
byte[] buffer;
int bufferSize;
public boolean isStartByte(byte firstChar){
if(firstChar=='A'){ // check if it works
return true;
}
else{
return false;
}
}
public void clearBytes(){
byte[] buffer=new byte[13];
bufferSize = 0;
}
private void appendBytes(byte[] buf){
System.arraycopy(buf, 0, buffer, bufferSize, buf.length);
bufferSize += buf.length;
}
public void checkData(){
tvAppend(errorCheck,buffer.toString());
}
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
//Defining a Callback which triggers whenever data is read.
@Override
public void onReceivedData(byte[] arg0) {
if(arg0!= null){
if(arg0.length > 0){
if (isStartByte(data[0])&& !startbytefound) { //look if its a new frame
startbytefound = true;
clearBytes(); // clears my buffer
}
appendBytes(arg0);
if(bufferSize >= iNBbyte && startbytefound){
bufferSize = iNBbyte;
byte[] buf = new byte[iNBbyte];
System.arraycopy(buffer, 0, buf, 0, bufferSize);
checkData(); //process the data
startbytefound = false;
}
}
}`
Maybe that would work. Check every passage with a Log.i() to see if everything's ok.
from usbserial.
hm..its still not working.. i mean its not displaying the string!
from usbserial.
for clearBytes..you mean to set the global variable buffer to new byte[13] right?
from usbserial.
Oh it looks like youre right..it never returns true for when byte==character..hmm im not sure how to do that conversion.
from usbserial.
Right i let a byte[] buffer you can erase byte[] it was an error.
Well you can log the bytes you receive (their values) knowing that you have an A coming just take the value and use that.
if for example you see that your 'A'=42 then use firstChar==42.
from usbserial.
Do you know why I am getting this error?
java.lang.ArrayIndexOutOfBoundsException: src.length=2 srcPos=0 dst.length=13 dstPos=13 length=2
at java.lang.System.arraycopy(Native Method)
at com.example.josceyn.walkerapp.UserDisplay.appendBytes(UserDisplay.java:108)
at com.example.josceyn.walkerapp.UserDisplay$1.onReceivedData(UserDisplay.java:137)
at com.felhr.usbserial.UsbSerialDevice$WorkerThread.onReceivedData(UsbSerialDevice.java:261)
at com.felhr.usbserial.UsbSerialDevice$WorkerThread.run(UsbSerialDevice.java:235)
from usbserial.
so it seems as though its trying to append to the buffer greater than 13 bytes..do i need to add some sort of check before appendBytes is called?
from usbserial.
Right thats because my buffer I create it with a length of 1024 to be sure not to have this kind of problem. You could add a check to be sure it never adds up to 13 or you can create the buffer at the beginning to 1024. Then for clearing you can do an Array.fill(buffer,0) to clear the buffer.
And thats why also i copy back the buffer to a new buffer of size 13 to get only the 13 bytes from the buffer
from usbserial.
So all you need to change in your code is in the clearbuffer change the new byte by array.fill and at the beginning create just once your buffer byte[] buffer = new byte[1024]
That should work now.
from usbserial.
So once found 13...then the extra stuff in the buffer, which is the next set of data is just gone? That doesnt seem like a good idea...
from usbserial.
Ohh actually nevermind.i understand now..sorry. i wl try this now and let you know. Thanks a loy
from usbserial.
Lot*
from usbserial.
it works..wooo..thank you so much!
from usbserial.
One more question for ya...i go to a new activity, a new intent, and its still running in the background...how do i stop the usb input..send a command to arduino?
from usbserial.
In the activity you should have the onPause method to override. In their you put a serial.close and on the onResume method you put the serial.open
from usbserial.
Okay sweet thanks. And when you want to recalibrate arduino, which is at the start of the activity, you could just send a 1 to the arduino telling it to perform thag, right?
from usbserial.
What do you mean by recalibrating? You mean reset? I think you can setDTR off and on for that
from usbserial.
Update : Solved all this issues after Buffering the Data received.
Hello,
I am using this library to read data from arduino and split it to different textviews. I do not know from read call back it gives the whole string to tvAppend function or just each characters it received ?
I use settext instead of append in the last line of code(runonUi) and can not see any data on my textview. It gives some random data. I am sending a string of 25 different integers seperated by ", " from arduino. Ex. 1,2,3,4,5,6,7,8...25 and receiving the same in android. But I am trying to get the whole string in android, then split it to "1", "2"..and display it using settext / append on my UI's textview.
So that if I receive 1,2,3,4,5,6,7,...25
Results will be
Textview 1 = 1
Textview 2 = 2 and so on.
Question is:
- Where do i split my data ? in tvAppend function or during received callback?
- How the data is received ?
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
tvAppend(textView, data);
this gives characters received or the whole string ?
from usbserial.
@felHR85
@OdysseusU
Please help if you get any idea on above question.
from usbserial.
hi,
Serial port opened successfully but when i try to show serial read data ,nothing shows Toast at usbSerial read callback method.
from usbserial.
Hello, I am facing problem while reading with the help of synchronous API, could someone please post the code for it. Thanks in advance.
from usbserial.
There are multiple solutiouns. If you don't high performance-critical code, you can code something like below. You can check start and stop characters or byte size etc.
private StringBuilder sb = new StringBuilder(); private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { @Override public void onReceivedData(byte[] arg0) { String data = new String(arg0, StandardCharsets.UTF_8); sb.append(data); if (data.endsWith("#") || data.endsWith("#\n")) { //Do what ever you want sb.setLength(0); } } };
Works like magic. Thank you.
from usbserial.
Related Issues (20)
- serialPort.getInputStream() causes android app to crash. HOT 1
- Losing Bytes? HOT 2
- getDeviceList empty HOT 2
- Newer FTDI devices use a 512 byte packet which is not supported by the existing FTDISerialDevice class HOT 1
- library still maintained ? HOT 1
- NPE at FTDISerialDevice.getBcdDevice()
- flash back on android 12?
- PL2303GC HOT 1
- UsbEndpoint.getAddress() method crashes the app.
- Port not opened and ACTION USB DEVICE NOT WORKING HOT 1
- any example project in hybrid ionic framework / native android ?
- I want to read data from USB whenever a USB device gives a flag. are there any methods to do so.?
- Issue with SDK > 31 on Android 12 HOT 1
- Write Thread and Read Thread Stops at any point of time HOT 1
- PL2303GL device not working HOT 2
- type and metro errors
- How to open the Arduino serial-port without it restarts
- java.lang.IllegalArgumentException: x.y.z: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
- syncRead fail after writing large syncWrite
- Host and Accessory communication(NOT AN ISSUE) HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from usbserial.