FreeBasic communication with Arduino logic error?
Re: FreeBasic communication with Arduino logic error?
Thanks for the image hosting site... I have no idea why imgur didn't work. .. probably something to do with money. lol
Anyway, I will post what I have, but I'm not out of ideas just yet.
I'm still learning... maybe I missed something simple.
If I can, I'd like to find it myself.
If not, I'll ask again... but hopefully, my next post will be have full working code, on both ends, and a simple diagram of the circuit. :)
Anyway, I will post what I have, but I'm not out of ideas just yet.
I'm still learning... maybe I missed something simple.
If I can, I'd like to find it myself.
If not, I'll ask again... but hopefully, my next post will be have full working code, on both ends, and a simple diagram of the circuit. :)
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: FreeBasic communication with Arduino logic error?
WOW! This turning out to be one great tutorial on serial programming.
I have been using PySerial for all of my serial comm programs, but I think that I will start at the beginning of this thread, and start giving the code examples a better look. Now , if you were to squeeze in some examples of how to implement some threading, that works in a meaningful way, that would cover a lot of serial comm programming.
Thanks for the great effort that is put into this.
I have been using PySerial for all of my serial comm programs, but I think that I will start at the beginning of this thread, and start giving the code examples a better look. Now , if you were to squeeze in some examples of how to implement some threading, that works in a meaningful way, that would cover a lot of serial comm programming.
Thanks for the great effort that is put into this.
Re: FreeBasic communication with Arduino logic error?
Ok... I know how crazy this image looks, but I'm not sure of another way to do it just yet. lol
Anyway, I removed any communication back from the Arduino, and the lag has pretty much gone away. The code for both sides is below, but the Arduino code hasn't changed much at all... basically just removed any data sent from that side.
FreeBasic code...
Arduino code...
Anyway, I removed any communication back from the Arduino, and the lag has pretty much gone away. The code for both sides is below, but the Arduino code hasn't changed much at all... basically just removed any data sent from that side.
FreeBasic code...
Code: Select all
#include "fbgfx.bi"
screenres 640,480,32,,FB.GFX_HIGH_PRIORITY
dim shared DEVICE_COM as string
dim as boolean conOk = false
dim as integer ARD = freefile
for i as integer = 1 to 10
DEVICE_COM = "COM" & str(i)
DEVICE_COM = "COM3"
if( open com(DEVICE_COM & ":9600,n,8,1,cs0,ds0,cd0,rs" for binary As #ARD) <> 0 ) then
print "error connecting to Arduino on " + DEVICE_COM
else
conOK = true
exit for
end if
next
if conOK then
print "Arduino connected on " + DEVICE_COM
sleep 1000,1
else
print "Failed to connect to Arduino"
sleep 5000, 1
end 1
end if
dim as string oTime, aTime, sHour, sMinute, sSecond, sTimeCode, temp
do
oTime = aTime
aTime = time
sTimeCode = ""
temp = bin(val(mid(aTime,1,2)), 6)
sHour = ""
for i as integer = len(temp) to 1 step -1
sHour+=mid(temp,i,1)
next
temp = bin(val(mid(aTime,4,2)), 6)
sMinute = ""
for i as integer = len(temp) to 1 step -1
sMinute+=mid(temp,i,1)
next
temp = bin(val(mid(aTime,7,2)), 6)
sSecond = ""
for i as integer = len(temp) to 1 step -1
sSecond+=mid(temp,i,1)
next
temp = sHour+sMinute+sSecond
for i as integer = len(temp) to 1 step -1
sTimeCode+=mid(temp,i,1)
next
sTimeCode+=chr(13)
screenlock
if oTime<>aTime then
cls
print sTimeCode
put #ARD,,sTimeCode
end if
screensync
screenunlock
sleep 3, 1
loop until multikey(FB.SC_ESCAPE)
Code: Select all
/*
Time Code Message Format:
hhhhhhmmmmmmssssss<CR>
hhhhhh = hours in binary text format ('0' or '1' characters only)
mmmmmm = minutes in binary text format ('0' or '1' characters only)
ssssss = seconds in binary text format ('0' or '1' characters only)
<CR> = end of message character chr(13)
19 bytes total
*/
const int SER = 12; // (595 pin 14)serial input line goes to the *first* shift register... daisy chain, so each QH(PIN 9) goes to the next SER, etc, etc...
const int SRCLK = 11; // (595 pin 11)the serial clock line, or the sync pulse, normal state is low... write, high, back to low, etc...
const int SRCLR = 10; // (595 pin 10)clear memory line, normal state is high... drop to low then back to high to clear memory...
const int RCLK = 9; // (595 pin 12)copy register line, normal state is low... send high then back to low to copy states...
const int OE = 8; // (595 pin 13)enable output line... send low to enable, high to disable...
const int TOTAL_SHIFT_PINS = 18;
void setup()
{
pinMode(SER, OUTPUT);
pinMode(SRCLK, OUTPUT);
pinMode(SRCLR, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(OE, OUTPUT);
Serial.begin( 9600 );
while ( !Serial )
delay(1);
//Serial.print( "Arduino is online - demo 5\n" );
//Serial.flush();
SR_clearRegisters();
SR_copyToStorage();
SR_turnOutputsOn();
}
void loop()
{
// preserve inTimeCode[] and inCount between calls,
// we may not receive the entire message in one loop through
static uint8_t inTimeCode[19];
static int inCount = 0;
int16_t ch = -1;
// read one char at a time (basically guarantees we never
// see the whole message in one call to loop()
ch = Serial.read();
// valid char? add it to inTimeCode[]
if ( ch != -1 )
{
inTimeCode[inCount] = ch;
inCount += 1;
}
// buffer full, but no CR? it's bad, start over
if ( (ch != 13) && (inCount == 19) )
{
inCount == 0;
//Serial.write( "bad time code, too long/n" );
//Serial.write( 13 );
}
// got a CR, but buffer not full yet? it's bad, start over
if ( (ch == 13) && (inCount != 19) )
{
inCount == 0;
//Serial.write( "bad time code, too short/n" );
//Serial.write( 13 );
}
// got a CR and buffer full? maybe it's OK... let's check
if ( (ch == 13) && (inCount == 19) )
{
for ( int i = 0; i < 18; ++i )
{
if ( (inTimeCode[i] != '0') && (inTimeCode[i] != '1') )
{
// bad data, start over
inCount == 0;
//Serial.write( "bad time code, invalid data/n" );
//Serial.write( 13 );
break;
}
}
// we already know last char is CR, so no need to check that
}
// still have a full buffer? it has to
// be good... we threw all the bad data away
if ( inCount == 19 )
{
SR_turnOutputsOff();
for ( int l = 0; l < 18; ++l )
{
if (inTimeCode[l] == 49 )
{
SR_shiftDataIn(HIGH);
}
else
{
SR_shiftDataIn(LOW);
}
//Serial.write( inTimeCode[l]);
//Serial.write( 32 );
}
SR_copyToStorage();
SR_turnOutputsOn();
//Serial.write( 13 );
//Serial.flush();
// done with the valid time code, start over, so we can get the next one
inCount = 0;
}
}
void SR_turnOutputsOn()
{
digitalWrite(OE, LOW);
}
void SR_turnOutputsOff()
{
digitalWrite(OE, HIGH);
}
void SR_clearRegisters()
{
digitalWrite(SRCLR, LOW);
digitalWrite(SRCLR, HIGH);
}
void SR_shiftDataIn(int data)
{
digitalWrite(SER, data);
digitalWrite(SRCLK, HIGH);
digitalWrite(SRCLK, LOW);
}
void SR_copyToStorage()
{
digitalWrite(RCLK, HIGH);
digitalWrite(RCLK, LOW);
}
Re: FreeBasic communication with Arduino logic error?
Have you tried with higher baudrate settings? (I never go below 19200, minimum)Dr_D wrote:Anyway, I removed any communication back from the Arduino, and the lag has pretty much gone away.
I've run my *very old Arduino* (pre Ono model) at speeds up to (and including) 115200 baud.
The real HW communication is after all USB, the COM port is just virtual (VCP).
Re: FreeBasic communication with Arduino logic error?
I haven't, but I will. Great idea. :)MrSwiss wrote:Have you tried with higher baudrate settings? (I never go below 19200, minimum)Dr_D wrote:Anyway, I removed any communication back from the Arduino, and the lag has pretty much gone away.
I've run my *very old Arduino* (pre Ono model) at speeds up to (and including) 115200 baud.
The real HW communication is after all USB, the COM port is just virtual (VCP).
Re: FreeBasic communication with Arduino logic error?
Hello folks,
This was a great read, thanks for a super tutorial on just exactly the topic I was searching for!
Can you tell me what the best strategy is for sending large amounts of data between a running FB application and an Arduino? Basically I want to update a group of member vars in a type instance with data constantly streaming in from the Arduino. Do I simply format the content of the variables as a string of text, serial print them, and then de-format them into variables again on reception? Or is there a better or less cumbersome way to do it?
Cheers,
Mike
This was a great read, thanks for a super tutorial on just exactly the topic I was searching for!
Can you tell me what the best strategy is for sending large amounts of data between a running FB application and an Arduino? Basically I want to update a group of member vars in a type instance with data constantly streaming in from the Arduino. Do I simply format the content of the variables as a string of text, serial print them, and then de-format them into variables again on reception? Or is there a better or less cumbersome way to do it?
Cheers,
Mike
Re: FreeBasic communication with Arduino logic error?
Yes, this should do.h4tt3n wrote:Do I simply format the content of the variables as a string of text, serial print them, and then de-format them into variables again on reception?
If cumbersome is meant to refer to string-splitting, there are some solutions available in this forum.h4tt3n wrote:Or is there a better or less cumbersome way to do it?
Since I'm to lazy currently (to search for them), just what I'm using:
Code: Select all
' (c) 2019-03-02, MrSwiss -- split a string into tokens (dyn. string array)
#Include "crt/string.bi" ' needed for: SplitString()
Declare Function SplitString(ByRef As Const String, ByRef As Const String, () As String) As Long
Private Function SplitString( _ ' uses CRT's strtok() Function
ByRef ssrc As Const String, _ ' string to be searched
ByRef chrs As Const String, _ ' character(s), to search for
res() As String _ ' result String array (ByRef, implicit!)
) As Long ' negative = error | >= 0 = OK
Dim As Long retv = 0 ' to hold return value
If Len(chrs) = 0 Then retv -= 2 ' nothing to search for, set err
If Len(ssrc) = 0 Then retv -= 1 ' no source string, set err
If retv < 0 Then Return retv ' return ERROR code (negative value)
Erase(res) ' delete dyn. array's content (if any)
Dim As String s = ssrc ' local variables: s = keeps ssrc
Dim As ZString Ptr psz = 0 ' result ptr (from strtok())
Dim As UInteger i = 0 ' counter, used as: array-index
psz = strtok(s, chrs) ' destroys s (must be reset! before reuse)
While psz ' just to get required array size
i += 1 : psz = strtok(0, chrs) ' i - 1 = UBound(res)
Wend
retv = i - 1 ' set arrays upper bound (return value)
ReDim res(0 To retv) ' size array (using retv)
i = 0 : s = ssrc : psz = 0 ' reset i, s and psz (for next run)
psz = strtok(s, chrs) ' get first token (string-part)
While psz ' run until psz is = 0
res(i) = *psz ' assign token to array
psz = strtok(0, chrs) ' get next token (string-part)
i += 1 ' increment index
Wend
Return retv ' upper array bound (lower = 0 = default)
End Function
Re: FreeBasic communication with Arduino logic error?
@h4tt3n: Another possibility could be to send and receive binary blobs, and packing and unpacking them as required:
This is faster but also have its drawbacks (and is no less cumbersome than parsing the data).
[Edit] There. I don't want anyone to be 'disinformed', the poor folks.
Code: Select all
'' Removed due to disinformation
[Edit] There. I don't want anyone to be 'disinformed', the poor folks.
Last edited by paul doe on Jan 21, 2020 1:00, edited 3 times in total.
Re: FreeBasic communication with Arduino logic error?
Nothing wrong with the concept, however, the code is "disinformation".
Reason: no Arduino can deal with Double (data-type) since, Single is
the only supported floating point type (aka: float, in AVR-C).
Reason: no Arduino can deal with Double (data-type) since, Single is
the only supported floating point type (aka: float, in AVR-C).
Re: FreeBasic communication with Arduino logic error?
Hi paul doe, my apologies. I've tried my best with Mr Swiss and I've asked a lot from many members, so I appreciate you hanging in there.
A much better response here might have been "Careful, fbc's datatypes may not match Arduino's... always check the data types." That would actually be pretty good advice when transmitting data between any 2 systems, through file, network, serial, carrier pigeon (old joke, RFC1149)....
OK, how about the logical approach? Even if I convince everyone to ignore the way you say things (that's just your personality), I do believe you are wrong anyway, Unless I am misreading the docs. I don't have the hardware mentioned so couldn't say for sure: See: https://www.arduino.cc/reference/en/lan ... es/double/
Maybe double is 4 bytes or 8 bytes? I think it depends on hardware. Also, Arduino double/float docs don't say what format of floating point either though on the surface it does appear to be IEEE-754. I didn't find a reference to confirm. I didn't look very hard either.
Hi MrSwiss. I thought we had a nice back-and-forth through email a while ago and I did try to offer some suggestions that might help you on the forums. But, it feels like I'm seeing the same old thing here and it's getting pretty tough to ask for more tolerance from everyone else.MrSwiss wrote:Nothing wrong with the concept, however, the code is "disinformation".
Reason: no Arduino can deal with Double (data-type) since, Single is
the only supported floating point type (aka: float, in AVR-C).
A much better response here might have been "Careful, fbc's datatypes may not match Arduino's... always check the data types." That would actually be pretty good advice when transmitting data between any 2 systems, through file, network, serial, carrier pigeon (old joke, RFC1149)....
OK, how about the logical approach? Even if I convince everyone to ignore the way you say things (that's just your personality), I do believe you are wrong anyway, Unless I am misreading the docs. I don't have the hardware mentioned so couldn't say for sure: See: https://www.arduino.cc/reference/en/lan ... es/double/
Maybe double is 4 bytes or 8 bytes? I think it depends on hardware. Also, Arduino double/float docs don't say what format of floating point either though on the surface it does appear to be IEEE-754. I didn't find a reference to confirm. I didn't look very hard either.
Re: FreeBasic communication with Arduino logic error?
Oh? No need for apologies, really. It's not like I invented the technique or something, after all. Even a (mildly) trained chimpanzee, and MrSwiss, could eventually figure it out so I don't see what the big deal is.coderJeff wrote:Hi paul doe, my apologies. I've tried my best with Mr Swiss and I've asked a lot from many members, so I appreciate you hanging in there.
...
Indeed, it's hardware dependent: Arduino Reference: Double. So MrSwiss' response is, um, 'disinformed'?coderJeff wrote: ...
OK, how about the logical approach? Even if I convince everyone to ignore the way you say things (that's just your personality), I do believe you are wrong anyway, Unless I am misreading the docs. I don't have the hardware mentioned so couldn't say for sure: See: https://www.arduino.cc/reference/en/lan ... es/double/
Maybe double is 4 bytes or 8 bytes? I think it depends on hardware. Also, Arduino double/float docs don't say what format of floating point either though on the surface it does appear to be IEEE-754. I didn't find a reference to confirm. I didn't look very hard either.
Re: FreeBasic communication with Arduino logic error?
Arduino Due is based on ARM technology, Atmel SAM3X8E, while the rest are pseudo 8-bitters.
I have the datasheet of the DUE here, and it doesn't say much about what FPU hardware it has. I assume that means it hasn't any, and typically other parts of its family, Cortex M3 doesn't seem to have it either.
So its higher speed and memory probably allows for more elaborate floating point emulation than the AVR ones, supporting both types.
Howver calling a 4-byte Single a Double is very confusing, and I can see where MrSwiss went wrong. It is counter-intuitive.
Anyway, the whole idea of single and double is that they stay the expected size. For a float type that scales with the architecture, C provides "float".
I can only guess why they did this, probably something historical, but IMHO it is not the best decision.
p.s. as for the whole discussion, a single to (real 64-bit) double is fairly easy afaik, just moving some bits. So if you want to keep the wire protocol universal (e.g. to use more precision with other hardware options), doing this even on Arduino AVR should be possible.
I have the datasheet of the DUE here, and it doesn't say much about what FPU hardware it has. I assume that means it hasn't any, and typically other parts of its family, Cortex M3 doesn't seem to have it either.
So its higher speed and memory probably allows for more elaborate floating point emulation than the AVR ones, supporting both types.
Howver calling a 4-byte Single a Double is very confusing, and I can see where MrSwiss went wrong. It is counter-intuitive.
Anyway, the whole idea of single and double is that they stay the expected size. For a float type that scales with the architecture, C provides "float".
I can only guess why they did this, probably something historical, but IMHO it is not the best decision.
p.s. as for the whole discussion, a single to (real 64-bit) double is fairly easy afaik, just moving some bits. So if you want to keep the wire protocol universal (e.g. to use more precision with other hardware options), doing this even on Arduino AVR should be possible.