The AI2 Bluetooth Client has a Receive Bytes block, which would receive a list of bytes values (0-255), which could be converted to text strings of 1s and 0s to show their bits.
But you already know it's the sixth bit of a byte that changes.
Is there a constancy to where in memory that byte is?
Or does its address change according to some pattern, like an array whose element size can be deduced from where it drops its residue?
But what kind of data element would reside in only one bit of a bytes?
That's really low level coding.
The last time I used those settings was pre-Internet, where I would keep lists of phone numbers to dial into to access bulletin board systems, each having their own preferred settings for the serial communication stream (a modem). The effect of setting the modem wrong was to see garbage letters on the screen.
I don't see much discussion of those bits these days, because software libraries handle this at low levels, and the Internet protocol stack hides all this. I have seen no reference to any of this in AI2 docs for the BlueTooth or Serial components.
What's worse, there is no pattern that I can see to when that 6th bit flips to 1 or to 0. It's not like a cosmic ray hit your RAM and burned out a bit, forcing a permanent 0 or 1.
I'm stumped.
If you can afford it, try some new hardware, or switch to BLE, which sounds similar but I am told is quite different.
Dear @gte, I've given only a very quick look to this thread, since I'm out for vacation, but I would suggest you a couple of things.
First of all, what Arduino bard are you using ? I see that your BT line is on Serial1: does this mean that you use a board with several Serial Lines, like the Mega ?
When I use the Mega board, the typical baudrate toward the HC05 that I use is 115200, without problems. For sure I've never changed Start/Stop/Parity bits as they worked fine as default. I see that you receive characters and with them you compose a string, then you work on strings: is this really necessary ? As Chris has already said, the less you transmit the lower is the possibility of error. One, trivial, test that you can do, is to print on the serial monitor of Arduino each character, as soon as it is received, instead of printing the whole string at the end. This is to be sure that the character (always the 6th ?) arrives already corrupted or it is a matter of some other conversion.
The received bytes are all stored in the same variable over and over again. I'm not sure if the address is the same every time, I can try to figure out how to write that to the screen.
If a different bluetooth hardware device will fix this, I'm certainly willing to use it. I guess ai2 negotiates that during the connection, it is configurable on the hc05.
I am using the mega. I have shortened the strings down as much as possible with me still (most of the time) knowing what they mean. I will make make them one or two characters as a last resort, however I need to be able to troubleshoot the code reasonably as well and I'm trying to find that balance before I give up on that and make it much harder on myself for the sake of chasing down this 6th bit error. I'm sure Chris's approach is ideal and I acknowledge that.
I will will try try the one character at a time screen print, that's a good idea.
A suggestion from the Arduino board is that two objects are trying to use the same memory location. I'm considering that possibility as well.
Ooops sorry, I've misunderstood your post: the 6th bit and not the 6th byte is wrong. This bit error affects all chacaters ?
If yes, therefore it seems effectively that the UART is decoding erroneously the incoming characters. To the purpose of troubleshooting that, it could help to echo on the Serial Monitor each character, as soon as received.
If you have changed the HC05 settings (i.e. start/stop/parity bits), please revert them to the factory ones.
I've seen that you have already tried to slow down the baudrate to 9600 without effect, but have you tried to simply change the Serial line ? For example, instead of using the Serial1 to try to use the Serial2 ?
The last comment about the use of the same memory location by different resources in the Arduino implementation, I've honestly never seen it, unless in the case of a very huge use of strings together with a OLED display (but on a UNO board, not a MEGA).
Another attempt could be to insert a short delay between chacaters, like:
But please be aware to NEVER use the delay(milliseconds) because it blocks completely the Arduino CPU. If you need to insert somewhere a delay, use the millis() instead.
If you send a code representing an action (command) and/or build that command within the Script, I am sure it will be successful, many Users are using this tried and trusted method. There are too many questions to ask about your current code but why build a car with square wheels when you can have round ones?
Here is another example, from a commercial educational toy:
#include <Servo.h>
Servo axis_one;
Servo axis_two;
Servo axis_three;
Servo grip; //0 30
int axis_one_ctr = 90;
int axis_two_ctr = 130; // min70 , max150
int axis_three_ctr = 40;
int x = 20;
int y = 50;
char in;
unsigned long lgUpdateTime;
void setup()
{
Serial.begin(9600);
axis_one.attach(8);
axis_two.attach(9);
axis_three.attach(10);
grip.attach(13);
axis_one.write(axis_one_ctr);
axis_two.write(axis_two_ctr);
axis_three.write(axis_three_ctr);
grip.write(0);
lgUpdateTime = millis();
}
void loop()
{
//Excute loop every 20 milliseconds, faster than the App sends to avoid buffer over-run
if((millis() - lgUpdateTime) > 20)
{
lgUpdateTime = millis();
if(Serial.available() > 0)
{
in = Serial.read();
switch (in)
{
case 'X':
axis_one_left();
break;
case 'x';
axis_one_right();
break;
case 'Y';
axis_two_forward();
break;
case 'y'
axis_two_backword();
break;
case 'Z'
axis_three_forward();
break;
case 'z'
axis_three_backword();
break;
case 'O'
axis_two_ctr = 1;
axis_two_forward();
break;
case 'C'
axis_two_ctr = 0;
axis_two_backword();
break;
case 'S'
//do something;
break;
}
}
}
}
void axis_one_right()
{
axis_one_ctr++;
axis_one.write(axis_one_ctr);
// Serial.println("Come");
if (axis_one_ctr > 170)
{
axis_one_ctr = 170;
}
}
void axis_one_left()
{
axis_one_ctr--;
axis_one.write(axis_one_ctr);
//Serial.println("Come");
if (axis_one_ctr < 10)
{
axis_one_ctr = 10;
}
}
void gripper_open()
{
}
void gripper_close()
{
}
void axis_two_forward()
{
axis_two_ctr++;
axis_two.write(axis_two_ctr);
if (axis_two_ctr > 150)
{
axis_two_ctr = 150;
}
}
void axis_two_backword()
{
axis_two_ctr--;
axis_two.write(axis_two_ctr);
// Serial.println("Come");
if (axis_two_ctr < 70)
{
axis_two_ctr = 70;
}
}
void axis_three_forward()
{
axis_three_ctr++;
axis_three.write(axis_three_ctr);
if (axis_three_ctr > 120)
{
axis_three_ctr = 120;
}
}
void axis_three_backword()
{
axis_three_ctr--;
axis_three.write(axis_three_ctr);
if (axis_three_ctr < 5)
{
axis_three_ctr = 5;
}
}
There is a lot to be said for keeping things simple
Thank you everyone, I really appreciate the guidance . Chris I will study your code example and learn from it.
So far the code has now been reliable, there were a few memory issues causing my problem one being a memset being called too often. Another was that I was trying to roll my own strtok because I didn't know that existed. I was able to remove about 100 lines of code afterwards.