I'm sending two commands when a switch is set to on and a single command when that switch is set to off, to an Arduino uC. The switch.on should send two commands separately via bluetooth, one after another, however the first command is being sent and not all of the second command is being sent (it becomes truncated) so it ends up being adjoined to the third command. If I have a single bluetooth send command in the switch on and a single bluetooth send command in the switch off, I've never seen the trampling.
Is this a common issue? A timing issue?
My bluetooth serial speed is 115200 and clock cycle is every 1mS. I tried 38400 as well, with the problem still existing.
Yes I need that for differentiation of the command type and the delimiters to indicate start and finish.
Can you explain how the faster clock cycle would cause a traffic jam? Do you mean a buffer issue with data?
The local variable bluetoothSendTextData contains whatever I'm sending it from the different app objects when I call it.
In the example in the first post, the switch swAutoOpenAfterDelay is sending "autoOpenAfterDelay=true" and "autoOpenTimeValue=true" when it is switched to on. The procedure bluetoothSendText receives "autoOpenAfterDelay=true" and prepends "<btwrite|" to it and appends ">" to it so the final send data will be "<btwrite|autoOpenAfterDelay=true>" and then the Arduino parses that based on the start and end characters of < and >, the command that precedes the | and the final parsing of the variable name and value based on the = symbol.
Do you think I'm overloading the bluetooth packet? In this example, I'm at 33 bytes plus the overhead. Is that problematic?
I set the second bluetooth call of the switch.on to "aOTV=1" (circled in green), rather than "autoOpenTimeValue=true" (circled in red) . It did not cause truncation in 5 tries, where as the more verbose bluetooth send data would cause truncation every time.
Is the packet limitation part of why the longer command truncates, but the shorter does not? Is there a way for me to be verbose in my bluetooth data? It seems there is also a timing component to this?
Well, it can be done more efficiently. First thing to note is that you do not need to mark the start of a value, you just need to delimit values. Instead of identifying a value with a word, use a single character.
These should also be single characters. You can have a Block List in your App or inline note so that you know which character represents which command.
If you can fit the data into a single packet, that removes complications - clearly in this case you can, as I have described.
post your .ino file (as a file) here, I can check that for you. Here is a simple example snippet, where the Script does the work:
void loop()
{
//Excute loop every 10 seconds
if((millis() - lgUpdateTime) > 10000)
{
lgUpdateTime = millis();
if(Serial.available() > 0)
{
IncomingValue = Serial.read();
switch (IncomingValue)
{
case '1':
servomotor1.write(0);//watering
break;
case '0':
servomotor1.write(120);//original position
break;
case 'M':
soilMoistureValue = analogRead(A0);
Serial.print(soilMoistureValue);
Serial.println();
break;
}
}
}
}
I have truncated the variables to initialisms, but they are four characters instead of one. I have not had any trampling yet, so that you for that suggestion.
Every once in a while I still get an issue with the communication where I will see the following btwrita|rOEV=true instead of btwrite|rOEV=true as an example.
I have uploaded the bluetooth serial data function and relevant data (I think) in the attached ino file. Can you tell me what do you think could cause the incorrect character recognition above and if there are any robust safeguards to handle this? Do I need some sort of repeat back handshake?
One of the items it does is monitor rpms, 500 to 10000 is the range and I would prefer it wasn't skipping by 200rpm increments when it was sending to the GUI.
If we just chose 4000rpm, that's 67 changes per second. Some of the other items I monitor for state change and only send an update when there is a state change, however at 1200 bytes, that's around 52 bluetooth packets per second (based on ChrisWard's 23 bytes per packet) and 52 updates per second would be plenty, however that's theoretical and not real world. With other transmissions going back and forth, I don't know what the real world number would be. One thing I don't have is the Delta rate for rpm change.
Let's start from 9600 baud and work upwards to bytes per second.
Assuming 10 bits per byte with parity and start/stop timing, that's 960 bytes per second.
Let's say you encode data as packets of
one byte identifying character
a colon ( : ) like in YAML
a five digit decimal number
an end of message delimiter character like \n
That's less than 9 bytes per message, so you can send 100 readings per second.
That's faster than the human eye can follow, and might even be fast enough to control a robot arm, give or take latency.
Regarding tracking RPM, you would save a lot of data traffic by calculating instantaneous RPM at the device, rather than by counting pulses over your data connection.
It's calculated by the uC and sent to the app as <currentRPM=4000> . I guess what I'm unclear about is the bluetooth packet send/receive process. To ensure I haven't made incorrect assumptions, is each packet 20 bytes plus overhead? If so this particular transmission would be
"<currentRPM=4000>\0\0\0"
and let's say I changed the code to say cRPM=4000, would the packet be
"<cRPM=4000>\0\0\0\0\0\0\0\0\0\0" or will it wait for more data and bundle it or is it a combo where it waits a predetermined short amount of time and if nothing else can be bundled, the data will be sent with the valid data and zeros appended?
If I understand that, I might be able to figure out if there is a potential for a bottleneck with the numbers you've provided.
btwrite|initGUI=trqe should have been btwrite|initGUI=true and it makes everything unreliable. I believe my hc05 device is bluetooth 2.0 and I haven't been able to find a good example of how the packet is structured when web searching, which means I'm probably using the wrong search terms.
Is there a way to implement a CRC with AppInventor for sending and receiving? And the ability to resend if the receiver requests because the CRC does not match?
I have seen discussions on this board of reliability of hc05 modules by actual hardware experimenters like @uskiara , @ChrisWard but have nothing specific for you on the bit errors.
I have seen charts of hc05 AT commands that let you query and specify parity bits for low level error checking, but am unaware of how the hardware and software react to inconsistencies.
You need help from people with more recent practical experience.
Start markers and End markers are not required and all of the code having to deal with them and the data is unnecessary. Use the simple single char code as per my example.
No it is not, it is currently powered via a USB connection.
No
Amazon. I did look at comparison pictures when I initially received it and based on the locations of the SMD chips, I determined mine was legitimate, it looks like the one with the green check mark next to it.
The wires are in a breadboard and are secure, right now it is on a desk so there is no movement
They are not shielded, would the suggestion be to buy shielded breadboard jumpers that have a second pin for ground? Or wrap a second wire around the Rx and Tx wires and ground it?
That's a good idea. I thought I had a pattern here with the first two being identical, but then the last one was different. After this I sent this message 20 times and it did not error out at all? I did notice another pattern, I converted the wrong characters to binary and it looks like the 6th bit of the byte is always the issue?
Is there a way in app inventor to have the actual binary values being sent, populate a multiline textbox?
Also, does AppInventor need the Stop Bit set to 0 (1 bit) or 1 (2 bits) and the Parity Bit set to anything other than 0 (None), 1 (Odd parity), 2 (Even parity)? Is this negotiated with the AppInventor bluetooth client and is there a best practice preferred settings for the HC05?
D: 01000100 (should have been)
@: 01000000 (what was received)
b: 01100010 (should have been)
f: 01100110 (what was received)
u: 01110101 (should have been)
q: 01110001 (what was received)
w: 01110111 (should have been)
s: 01110011 (what was received)
r: 01110010 (should have been)
v: 01110110 (what was received)