1. [Eu 3.1]How to send many files to Arduino via USB?

Hi all, I used to be here and contribute a little, not much, been away, not really back, not any more proficient coding than I was then, but I do need some help trying to be able to load a bunch of .mp3 files into a MP3/SDcard daughter board ("shield") on an Arduino Uno.

I have a VS1053 MP3 Codec + SD dboard to use with Arduino Uno, which can store .mp3 files on the SD card to play through the VS1053, but I'll be mounting the assembly in such a way that makes it too hard to remove the microSD card from it to routinely change its contents; so I'm looking for a way to command delete specific files and then add a directory full of new .mp3 via the USB link from my laptop.

The command delete might be easy, through the Arduino IDE and its serial monitor, and I should be able to easily enough reprise selecting a directory & working through it here on the computer side, but I know nothing about serial, nor if Euphoria can even access the USB port.

Don't think I saw anything here that was directly related, though I might have missed it, so any help would be appreciated.

Dan

new topic     » topic index » view message » categorize

2. Re: [Eu 3.1]How to send many files to Arduino via USB?

DanM_anew said...

Hi all, I used to be here and contribute a little, not much, been away, not really back, not any more proficient coding than I was then, but I do need some help trying to be able to load a bunch of .mp3 files into a MP3/SDcard daughter board ("shield") on an Arduino Uno.

I have a VS1053 MP3 Codec + SD dboard to use with Arduino Uno, which can store .mp3 files on the SD card to play through the VS1053, but I'll be mounting the assembly in such a way that makes it too hard to remove the microSD card from it to routinely change its contents; so I'm looking for a way to command delete specific files and then add a directory full of new .mp3 via the USB link from my laptop.

The command delete might be easy, through the Arduino IDE and its serial monitor, and I should be able to easily enough reprise selecting a directory & working through it here on the computer side, but I know nothing about serial, nor if Euphoria can even access the USB port.

Don't think I saw anything here that was directly related, though I might have missed it, so any help would be appreciated.

Dan

Hello Dan.

I'm not very familiar with Arduino, but i do play with the Propeller micro-controller. I have been working on a library that can interface with FTDI USB serial devices, and it works well, although it is incomplete.

Bummer, i just looked it up, and unfortunately, "The Uno differs from all preceding boards in that it does not use the FTDI USB-to-serial driver chip. Instead, it features the Atmega16U2 (Atmega8U2 up to version R2) programmed as a USB-to-serial converter." I haven't looked into it, but if the driver is as simple as FTDI, it shouldn't be too hard to wrap the dll file. If you can find the documentation for that, it may be possible to write a euphoria wrapper without too much trouble. After you get the basic tx/rx working, you would have to spend some time designing a communication protocol and some sort of command system (if there isn't already a library out there for that).

new topic     » goto parent     » topic index » view message » categorize

3. Re: [Eu 3.1]How to send many files to Arduino via USB?

ryanj said...
DanM_anew said...

... I have a VS1053 MP3 Codec + SD dboard to use with Arduino Uno, which can store .mp3 files on the SD card to play through the VS1053, but I'll be mounting the assembly in such a way that makes it too hard to remove the microSD card from it to routinely change its contents; so I'm looking for a way to command delete specific files and then add a directory full of new .mp3 via the USB link from my laptop.

... but I know nothing about serial, nor if Euphoria can even access the USB port.

Don't think I saw anything here that was directly related, though I might have missed it, so any help would be appreciated.

Dan

Hello Dan.

I'm not very familiar with Arduino, but i do play with the Propeller micro-controller. I have been working on a library that can interface with FTDI USB serial devices, and it works well, although it is incomplete.

Bummer, i just looked it up, and unfortunately, "The Uno differs from all preceding boards in that it does not use the FTDI USB-to-serial driver chip. Instead, it features the Atmega16U2 (Atmega8U2 up to version R2) programmed as a USB-to-serial converter." I haven't looked into it, but if the driver is as simple as FTDI, it shouldn't be too hard to wrap the dll file. If you can find the documentation for that, it may be possible to write a euphoria wrapper without too much trouble. After you get the basic tx/rx working, you would have to spend some time designing a communication protocol and some sort of command system (if there isn't already a library out there for that).

From some things I've seen here, it seems that perhaps I can just deal with the USB port as a system recognized Com port? I don't know if I can specify baud, parity, & checksum for USB that way, and I'd have to arrange some kind of handshaking with the Uno so it has time to deal with receiving & handling the data, but does that approach seem like it's reasonable??

And if so, does anyone have any suggestions about setting USB baud, parity, and creating checksum, or any examples?

new topic     » goto parent     » topic index » view message » categorize

4. Re: [Eu 3.1]How to send many files to Arduino via USB?

DanM_anew said...
ryanj said...
DanM_anew said...

... I have a VS1053 MP3 Codec + SD dboard to use with Arduino Uno, which can store .mp3 files on the SD card to play through the VS1053, but I'll be mounting the assembly in such a way that makes it too hard to remove the microSD card from it to routinely change its contents; so I'm looking for a way to command delete specific files and then add a directory full of new .mp3 via the USB link from my laptop.

... but I know nothing about serial, nor if Euphoria can even access the USB port.

Don't think I saw anything here that was directly related, though I might have missed it, so any help would be appreciated.

Dan

Hello Dan.

I'm not very familiar with Arduino, but i do play with the Propeller micro-controller. I have been working on a library that can interface with FTDI USB serial devices, and it works well, although it is incomplete.

Bummer, i just looked it up, and unfortunately, "The Uno differs from all preceding boards in that it does not use the FTDI USB-to-serial driver chip. Instead, it features the Atmega16U2 (Atmega8U2 up to version R2) programmed as a USB-to-serial converter." I haven't looked into it, but if the driver is as simple as FTDI, it shouldn't be too hard to wrap the dll file. If you can find the documentation for that, it may be possible to write a euphoria wrapper without too much trouble. After you get the basic tx/rx working, you would have to spend some time designing a communication protocol and some sort of command system (if there isn't already a library out there for that).

From some things I've seen here, it seems that perhaps I can just deal with the USB port as a system recognized Com port? I don't know if I can specify baud, parity, & checksum for USB that way, and I'd have to arrange some kind of handshaking with the Uno so it has time to deal with receiving & handling the data, but does that approach seem like it's reasonable??

And if so, does anyone have any suggestions about setting USB baud, parity, and creating checksum, or any examples?

Hi Dan,

I know almost nothing about Arduino, but I had success to interface with Prolif PL-2303HXD USB-bridge using virtual COM ports and Jacques' serial port library. Please, take a look at http://openeuphoria.org/forum/113149.wc#113149

- Fernando

new topic     » goto parent     » topic index » view message » categorize

5. Re: [Eu 3.1]How to send many files to Arduino via USB?

Fernando said...

Hi Dan,

I know almost nothing about Arduino, but I had success to interface with Prolif PL-2303HXD USB-bridge using virtual COM ports and Jacques' serial port library. Please, take a look at http://openeuphoria.org/forum/113149.wc#113149

- Fernando

Thanks Fernando, I did see that thread, amongst a few others, so I'll be looking into Jacques' serial port library. And your code example in particular, too! I pretty much live and breathe by examples!

Is there anything anyone can tell me about handshaking, as I'm sure I'll have to have the Uno 'sketch' (their word for program) tell the computer to wait while it handles chunks of data from each file.

[edit] and what about "checksum", how to create/assert/check?

Dan

new topic     » goto parent     » topic index » view message » categorize

6. Re: [Eu 3.1]How to send many files to Arduino via USB?

Hi Fernando,

This'll be slow, so, just to be sure I understand, your example requires a physical 'loopback' wiring on a physical serial port in order to echo typed characters, right?

So, if I am just trying to send through USB, without any loopback in place, it should work just fine to send through USB, without echo, since the echo is only from the physical connection (which in my case is nonexistant), right?

include serial.ew  
include get.e  
include misc.e  
  
object val  
integer port, a  
atom hCom1  
  
constant MAXDWORD=#FFFFFFFF  
constant ESC=27  
  
port = 5				-- ADJUST TO YOUR PORT  
   
hCom1 = serial_open(port)  
if hCom1 < 0 then  
	printf(1,"Error opening port %d.\n\n",port)  
	abort(1)  
end if  
-- http://msdn.microsoft.com/en-us/library/aa363190%28v=VS.85%29.aspx  
-- A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant 
-- and ReadTotalTimeoutMultiplier members,  
-- specifies that the read operation is to return immediately with the bytes  
--   that have already been received, even if no bytes have been received.  
SetCommTimeouts(hCom1,{MAXDWORD,0,0,0,0})  
SetCommState(hCom1, "baud:9600;parity:none;bits:8;stop:1;control:none")  
  
puts(1,"1) Connect TX and RX (loopback) (pins 2 and 3 in the DB9 connector).\n" &  
       "2) Every key you hit will be send and received by serial port and echoed to the screen.\n" &  
       "3) ESC abort.\n")  
PurgeComm(hCom1,PURGE_RXCLEAR)  
while 1 do  
	a = get_key()  
	if a != -1 then  
		if a = ESC then  
			puts(1,"\nAborted!\n")  
			abort(0)  
		end if  
		serial_puts(hCom1, a)				-- SEND KEY CODE TO SERIAL PORT  
	end if  
	val = serial_getc(hCom1)  
	if val != -1 then  
		puts(1,val)  
	end if  
end while  
new topic     » goto parent     » topic index » view message » categorize

7. Re: [Eu 3.1]How to send many files to Arduino via USB?

Hi again Fernando,

Hmpff! Your example simply worked! A Uno program waiting for serial input actually received characters sent via USB from your serial example, turned an led appropriately on or off, and even sent programmed text response back & was displayed back here! I can't stand it when things WORK, it really confuses me, it's so unexpected! smile

Now let's see if I can figure out how to send large amounts of data, multiple files, & have them get stored & named on a SD card connected to the Arduino Uno, & how long that'll take me.

Your example is a life saver, a workable starting point, thank you!

new topic     » goto parent     » topic index » view message » categorize

8. Re: [Eu 3.1]How to send many files to Arduino via USB?

Now to try to continue, regarding data flow control.

I presume I need to have the Arduino Uno program assess whether a data block received has been correctly received, hence some need for checksum. Does anyone have any suggestion for how to create a checksum?

And, in the command, SetCommState(hCom1, "baud:9600;parity:none;bits:8;stop:1;control:none"), I presume control should ultimately be set to software, but I don't understand what effect/use "flags" has after being set in the following snippet of code from SetCommState, nor how I could then use whatever effect it has from within an Arduino program; the best I've thought of is that the host serial program has to send 1 block of file data and then wait for the Arduino program to send back a command to either send next block, or resend previous block, or finished with the file, go on to next file. But is that kind of control implicit somehow within those flags, or is it rather completely outside the named "flow control" & its flags?

      elsif equal(split[i][1],"control") then  -- flow control 
         if equal(split[i][2],"hard") then -- hardware control 
             flags = set_bits(flags,{3,4,6,7,8,14}) 
             flags = clear_bits(flags,{5,9,10,13}) 
         elsif equal(split[i][2],"soft") then  -- software control 
             flags = clear_bits(flags,{3,4,7,8,14}) 
             flags = set_bits(flags,{9,10}) 
         elsif equal(split[i][2],"none") then  -- no control 
             flags = clear_bits(flags,{3,4,5,6,7,9,10,11,12,13,14,15}) 
             flags = set_bits(flags,{8}) 
         end if 
      end if  
new topic     » goto parent     » topic index » view message » categorize

9. Re: [Eu 3.1]How to send many files to Arduino via USB?

DanM_anew said...

Now to try to continue, regarding data flow control.

I presume I need to have the Arduino Uno program assess whether a data block received has been correctly received, hence some need for checksum. Does anyone have any suggestion for how to create a checksum?

Hi Dan,

A simple approach is to sum all bytes of the data and take the least significant byte of this sum as the checksum. Then, it's common to 2-complement (to obtain the negative) that checksum and append it to the data. The receiver of the data, then, calculate its checksum and if it's different from zero, probably there was an error in the communication.

A more robust algorithm is the Fletcher's checksum (http://en.wikipedia.org/wiki/Fletcher%27s_checksum). It's a position dependent checksum.

Some possible implementations in Euphoria (3.1):

function Fletcher16(sequence data) 
integer sum1, sum2 
	sum1 = 0 
	sum2 = 0 
	for i = 1 to length(data) do 
		sum1 = remainder(sum1 + data[i], 255) 
		sum2 = remainder(sum2 + sum1, 255) 
	end for 
	return { sum2, sum1 } 
end function 

or

function Fletcher16(sequence data) 
integer sum1, sum2 
	sum1 = 0 
	sum2 = 0 
	for i = 1 to length(data) do 
		sum1 += data[i] 
		if sum1 >= 255 then sum1 -= 255 end if 
		sum2 += sum1 
	end for 
	sum2 = remainder(sum2,255) 
	return { sum2, sum1 } 
end function 

With the following function, you could take your data and append it with two bytes so that the Fletcher's checksum will be zero:

function AppendFletcher16(sequence data) 
sequence csum 
integer c0, c1 
	csum = Fletcher16(data) 
	c0 = 255 - remainder(csum[2] + csum[1],255) 
	c1 = 255 - remainder(csum[2] + c0,255) 
	return  data & c0 & c1 
end function 

Then the receiver computes the Fletcher's checksum and if it's different from zero, probably there was an error in the communication.

An even more robust approach is compute the CRC (cyclic redundancy code)(http://en.wikipedia.org/wiki/Cyclic_redundancy_check).

Here is one kind of a CRC-16 implementation:

constant TabCRCLo = 
	{ 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #01, #C0, #80, #41, 
	#00, #C1, #81, #40, #00, #C1, #81, #40, #01, #C0, 
	#80, #41, #01, #C0, #80, #41, #00, #C1, #81, #40, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #00, #C1, 
	#81, #40, #01, #C0, #80, #41, #01, #C0, #80, #41, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #00, #C1, 
	#81, #40, #00, #C1, #81, #40, #01, #C0, #80, #41, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #00, #C1, #81, #40, 
	#01, #C0, #80, #41, #01, #C0, #80, #41, #00, #C1, 
	#81, #40, #01, #C0, #80, #41, #00, #C1, #81, #40, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #00, #C1, #81, #40, 
	#01, #C0, #80, #41, #00, #C1, #81, #40, #01, #C0, 
	#80, #41, #01, #C0, #80, #41, #00, #C1, #81, #40, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #01, #C0, #80, #41, 
	#00, #C1, #81, #40, #00, #C1, #81, #40, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #01, #C0, #80, #41, 
	#01, #C0, #80, #41, #00, #C1, #81, #40, #01, #C0, 
	#80, #41, #00, #C1, #81, #40, #00, #C1, #81, #40, 
	#01, #C0, #80, #41, #01, #C0, #80, #41, #00, #C1, 
	#81, #40, #00, #C1, #81, #40, #01, #C0, #80, #41, 
	#00, #C1, #81, #40, #01, #C0, #80, #41, #01, #C0, 
	#80, #41, #00, #C1, #81, #40 
	} 
 
constant TabCRCHi = 
	{ 
	#00, #C0, #C1, #01, #C3, #03, #02, #C2, #C6, #06, 
	#07, #C7, #05, #C5, #C4, #04, #CC, #0C, #0D, #CD, 
	#0F, #CF, #CE, #0E, #0A, #CA, #CB, #0B, #C9, #09, 
	#08, #C8, #D8, #18, #19, #D9, #1B, #DB, #DA, #1A, 
	#1E, #DE, #DF, #1F, #DD, #1D, #1C, #DC, #14, #D4, 
	#D5, #15, #D7, #17, #16, #D6, #D2, #12, #13, #D3, 
	#11, #D1, #D0, #10, #F0, #30, #31, #F1, #33, #F3, 
	#F2, #32, #36, #F6, #F7, #37, #F5, #35, #34, #F4, 
	#3C, #FC, #FD, #3D, #FF, #3F, #3E, #FE, #FA, #3A, 
	#3B, #FB, #39, #F9, #F8, #38, #28, #E8, #E9, #29, 
	#EB, #2B, #2A, #EA, #EE, #2E, #2F, #EF, #2D, #ED, 
	#EC, #2C, #E4, #24, #25, #E5, #27, #E7, #E6, #26, 
	#22, #E2, #E3, #23, #E1, #21, #20, #E0, #A0, #60, 
	#61, #A1, #63, #A3, #A2, #62, #66, #A6, #A7, #67, 
	#A5, #65, #64, #A4, #6C, #AC, #AD, #6D, #AF, #6F, 
	#6E, #AE, #AA, #6A, #6B, #AB, #69, #A9, #A8, #68, 
	#78, #B8, #B9, #79, #BB, #7B, #7A, #BA, #BE, #7E, 
	#7F, #BF, #7D, #BD, #BC, #7C, #B4, #74, #75, #B5, 
	#77, #B7, #B6, #76, #72, #B2, #B3, #73, #B1, #71, 
	#70, #B0, #50, #90, #91, #51, #93, #53, #52, #92, 
	#96, #56, #57, #97, #55, #95, #94, #54, #9C, #5C, 
	#5D, #9D, #5F, #9F, #9E, #5E, #5A, #9A, #9B, #5B, 
	#99, #59, #58, #98, #88, #48, #49, #89, #4B, #8B, 
	#8A, #4A, #4E, #8E, #8F, #4F, #8D, #4D, #4C, #8C, 
	#44, #84, #85, #45, #87, #47, #46, #86, #82, #42, 
	#43, #83, #41, #81, #80, #40 
	} 
 
 
function CRC(sequence data) 
integer i, CRCHi, CRCLo 
	CRCHi = #00 
	CRCLo = #00 
	for j = 1 to length(data) do 
		i = xor_bits(CRCLo, data[j])								 
		i += 1															 
		CRCLo = xor_bits(CRCHi,TabCRCLo[i])						 
		CRCHi = TabCRCHi[i]											 
	end for 
	return { CRCLo, CRCHi }											 
end function 
 

- Fernando

new topic     » goto parent     » topic index » view message » categorize

10. Re: [Eu 3.1]How to send many files to Arduino via USB?

Thank you Fernando,

Right now I'm having trouble getting Arduino-Euphoria to shake hands: I can read & send files from computer to Arduino, but am not yet getting Arduino to read correctly enough to try to tell Euphoria when to send & when to wait. Right now I'm just sending all files contents as fast as Eu-term can send it, but I need Arduino to respond correctly before I can make Eu-term send correctly. (What I mean is that I'm sending a series of blocks comprising each file, but haven't got Arduino to process the blocks correctly, so the sending of the blocks just runs amok.)

So I jumped too far ahead wondering about checksum, I'll have to go back to work on arduino before I can try to improve the Euphoria 'terminal' side.

Dan

new topic     » goto parent     » topic index » view message » categorize

11. Re: [Eu 3.1]How to send many files to Arduino via USB?

I don't know if this helps, but I designed a packet format for serial communication with the Propeller IC:

┌───────┐ 
│01(SOH)│ 
├───────┤ 
│DataLen│ 
├───────┤ 
│02(STX)│ 
├───────┤ 
│MsgType│ 
├───────┤ 
│MsgDat0│ 
│   :   │ 
│   :   │ 
│   :   │ 
│MsgDatX│ 
├───────┤ 
│03(ETX)│ 
├───────┤ 
│CRC16b0│ 
├───────┤ 
│CRC16b1│ 
├───────┤ 
│04(EOT)│ 
└───────┘ 

By setting up logic to look for the byte values in the right places, you can receive variable size packets and extract the data out of them. I haven't had the need to implement the CRC check yet, so it's just a place-holder.

new topic     » goto parent     » topic index » view message » categorize

12. Re: [Eu 3.1]How to send many files to Arduino via USB?

ryanj said...

I don't know if this helps, but I designed a packet format for serial communication with the Propeller IC:

┌───────┐ 
│01(SOH)│ 
├───────┤ 
│DataLen│ 
├───────┤ 
│02(STX)│ 
├───────┤ 
│MsgType│ 
├───────┤ 
│MsgDat0│ 
│   :   │ 
│   :   │ 
│   :   │ 
│MsgDatX│ 
├───────┤ 
│03(ETX)│ 
├───────┤ 
│CRC16b0│ 
├───────┤ 
│CRC16b1│ 
├───────┤ 
│04(EOT)│ 
└───────┘ 

By setting up logic to look for the byte values in the right places, you can receive variable size packets and extract the data out of them. I haven't had the need to implement the CRC check yet, so it's just a place-holder.

Thanks ryanj, that does help! I had a vague idea like that in mind, but your's is much cleaner! :) I'll definitely have to put DataLength in, that's already my first task, to do it properly in relation to data types and the correct reception & interpretation by the Uno sketch/program; and the file name a block is going to will be necessary too.

I see that SOH is Start Of Heading, STX is Start Of Text, and ETX is end of text. I presume EOT is just end of block? And do you use any special characters sent to define the different parts of the format, or is that just taken care of by the defined position in the block? The BlockLength should work for me, the only variation in block length will be the last block from a file, or a file that's shorter than the defined block size I'll send.

I'm not sure if the Uno has enough memory to support CRC, but I presume I could just use, at least for now, one of the suggestions Fernando made for checksum in their place.

Thanks again!

Dan

new topic     » goto parent     » topic index » view message » categorize

13. Re: [Eu 3.1]How to send many files to Arduino via USB?

DanM_anew said...

I see that SOH is Start Of Heading, STX is Start Of Text, and ETX is end of text. I presume EOT is just end of block? And do you use any special characters sent to define the different parts of the format, or is that just taken care of by the defined position in the block? The BlockLength should work for me, the only variation in block length will be the last block from a file, or a file that's shorter than the defined block size I'll send.

I looked at an ASCII chart and picked those particular ASCII codes, because i thought they made the most sense. Here is the Euphoria version for reading a packet, to get you started. It gets an unknown number of bytes for the serial port, and attempts to process it until enough bytes come in to make the complete packet. If it takes too long, it times out.

constant 
SOH = 1,  
STX = 2, 
ETX = 3, 
EOT = 4, 
MAXMSGLEN = 96 
 
procedure device_read_task() 
    atom Timeout, MsgLen, MsgCRC 
    sequence InBuffer = {}, MsgData 
    object inb 
     
    while 1 do 
        Timeout = time() 
        inb = usb:Read() --read bytes in buffer 
        if sequence(inb) and length(inb) > 0 then 
            Timeout = time() 
            InBuffer &= inb 
        end if 
     
        MsgData = {} 
        for b = 1 to length(InBuffer) do 
            if (length(InBuffer) - b + 1) > 7 then 
                if InBuffer[b] = SOH then 
                    MsgLen = InBuffer[b+1] 
                    if MsgLen <= MAXMSGLEN and InBuffer[b+2] = STX then 
                        if length(InBuffer) >= b + 7 + MsgLen - 1 then 
                            if InBuffer[b+3+MsgLen] = ETX and InBuffer[b+3+MsgLen+3] = EOT then 
                                MsgData = InBuffer[b+3..b+3+MsgLen-1] 
                                 
                                process_message(MsgData[1], MsgData[2..$]) --process packet data (msgtype, msgdata) 
                                 
                                InBuffer = {} 
                                exit 
                            end if 
                        end if 
                    end if 
                end if 
            end if 
        end for 
         
        if time() - Timeout > 0.5 then 
            InBuffer = {} 
        end if 
         
        task_yield() 
    end while 
end procedure 
new topic     » goto parent     » topic index » view message » categorize

14. Re: [Eu 3.1]How to send many files to Arduino via USB?

ryanj said...
DanM_anew said...

I see that SOH is Start Of Heading, STX is Start Of Text, and ETX is end of text. I presume EOT is just end of block? And do you use any special characters sent to define the different parts of the format, or is that just taken care of by the defined position in the block? The BlockLength should work for me, the only variation in block length will be the last block from a file, or a file that's shorter than the defined block size I'll send.

I looked at an ASCII chart and picked those particular ASCII codes, because i thought they made the most sense. Here is the Euphoria version for reading a packet, to get you started. It gets an unknown number of bytes for the serial port, and attempts to process it until enough bytes come in to make the complete packet. If it takes too long, it times out.

constant 
SOH = 1,  
STX = 2, 
ETX = 3, 
EOT = 4, 
MAXMSGLEN = 96 
 
procedure device_read_task() 
    atom Timeout, MsgLen, MsgCRC 
    sequence InBuffer = {}, MsgData 
    object inb 
     
    while 1 do 
        Timeout = time() 
        inb = usb:Read() --read bytes in buffer 
        if sequence(inb) and length(inb) > 0 then 
            Timeout = time() 
            InBuffer &= inb 
        end if 
     
        MsgData = {} 
        for b = 1 to length(InBuffer) do 
            if (length(InBuffer) - b + 1) > 7 then 
                if InBuffer[b] = SOH then 
                    MsgLen = InBuffer[b+1] 
                    if MsgLen <= MAXMSGLEN and InBuffer[b+2] = STX then 
                        if length(InBuffer) >= b + 7 + MsgLen - 1 then 
                            if InBuffer[b+3+MsgLen] = ETX and InBuffer[b+3+MsgLen+3] = EOT then 
                                MsgData = InBuffer[b+3..b+3+MsgLen-1] 
                                 
                                process_message(MsgData[1], MsgData[2..$]) --process packet data (msgtype, msgdata) 
                                 
                                InBuffer = {} 
                                exit 
                            end if 
                        end if 
                    end if 
                end if 
            end if 
        end for 
         
        if time() - Timeout > 0.5 then 
            InBuffer = {} 
        end if 
         
        task_yield() 
    end while 
end procedure 

Oh, ok, there ARE code characters defining the starts of the different fields in the block sent, good to know! I'll study your code, I'm going in the other direction, sending from an Eu coded 'terminal' pgm, received on Uno with C or C plus plus subset or something like that, but the general idea has to be about the same in order that the handshaking work, so I'll try to transpose that into the Uno code! smile .

Here's what I'm doing here in Eu terminal just after a send of a block to the Uno, I can't really tell if it's doing what I want, it's supposed to be waiting for a response FROM the Uno, indicating eventually if it's ok to send another block (or resend same one again):

     while 1 do 
--     puts(1, "this is in the while to receive echo" & "\n") 
 
--read count bytes from serial port 
--global function serial_get_bytes(atom hCom, integer count) 
 
            val = {} 
     		val = serial_getc(hCom1)  -- AND THIS RECEIVES AND DISPLAYS ANY RESPONSE 
	        if val != -1 then 
	          val &= serial_get_bytes(hCom1,length(chunk)) -- SHOULD get whole echo 
              puts(1, "\nIT GOT AN ECHO!  " & val & "\n") 
              puts(1, "length of echo= " & sprint(length(val)) & "\n\n") 
	          exit 
            end if 
     end while 

Does it seem like it's trying to do what I want? All I'm wanting it to do is wait to receive the handshake from the Uno, one or two responses, "all ok, send more", or "resend last block" eventually, but I'm not sure I'm doing it right in this initial version.

new topic     » goto parent     » topic index » view message » categorize

15. Re: [Eu 3.1]How to send many files to Arduino via USB?

DanM_anew said...

Oh, ok, there ARE code characters defining the starts of the different fields in the block sent, good to know! I'll study your code, I'm going in the other direction, sending from an Eu coded 'terminal' pgm, received on Uno with C or C plus plus subset or something like that, but the general idea has to be about the same in order that the handshaking work, so I'll try to transpose that into the Uno code! smile .

Here's what I'm doing here in Eu terminal just after a send of a block to the Uno, I can't really tell if it's doing what I want, it's supposed to be waiting for a response FROM the Uno, indicating eventually if it's ok to send another block (or resend same one again):

     while 1 do 
--     puts(1, "this is in the while to receive echo" & "\n") 
 
--read count bytes from serial port 
--global function serial_get_bytes(atom hCom, integer count) 
 
            val = {} 
     		val = serial_getc(hCom1)  -- AND THIS RECEIVES AND DISPLAYS ANY RESPONSE 
	        if val != -1 then 
	          val &= serial_get_bytes(hCom1,length(chunk)) -- SHOULD get whole echo 
              puts(1, "\nIT GOT AN ECHO!  " & val & "\n") 
              puts(1, "length of echo= " & sprint(length(val)) & "\n\n") 
	          exit 
            end if 
     end while 

Does it seem like it's trying to do what I want? All I'm wanting it to do is wait to receive the handshake from the Uno, one or two responses, "all ok, send more", or "resend last block" eventually, but I'm not sure I'm doing it right in this initial version.

It's good to use the same packet format both directions, whether sending large data or something as small as an acknowledgment message. If you use the first byte of the message to identify the message type, you can create a list of message type constants and handle the incoming packets easily with switch/case or if/then statements, and even handle errors and retries easily.

new topic     » goto parent     » topic index » view message » categorize

16. Re: [Eu 3.1]How to send many files to Arduino via USB?

ryanj said...

It's good to use the same packet format both directions, whether sending large data or something as small as an acknowledgment message. If you use the first byte of the message to identify the message type, you can create a list of message type constants and handle the incoming packets easily with switch/case or if/then statements, and even handle errors and retries easily.

Oh, ok, I see what you mean; I was trying to approach it incrementally, make both sides do a little toward what it needs to do, then a little more, etc, whereas you've taken a programming approach ( ! ), and designed the complete procedure out of whole cloth, smile . Not sure how much trouble I'll have, though, trying to change Eu code to Uno C plus plus sketch, but I'll work on it, thanks!

Dan

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu