News:

Let's find out together what makes a PIC Tick!

Main Menu

RSOut of Byte Array

Started by Trikkitt, Aug 07, 2021, 06:31 PM

Previous topic - Next topic

Trikkitt

I'm trying to puzzle my way around the RSOut command.  I can't use the hardware serial ports because I'm already using both of them already via interrupts.

The challenge is to output a 10 byte array of binary data via RSout or Serout (I really don't mind) at 9600bps.  So far my attempts do not work.  All the examples in the manual use plain text, nothing explains how to send binary data.  Any ideas?  I know the data contains bytes that are zero, so suspect it is being interpreted as an end of string.  However there is nothing documented that I've found to send it as binary data.  Serial commands one at a time don't work, I suspect because the gap between each byte is a little too long and results in a framing error.

Here is the code:

  soundCheckSum=-(Version_Byte + Command_Length + cmd + Acknowledge + cmdp1 + cmdp2)
  SoundCmd[0]=Start_Byte
  SoundCmd[1]=Version_Byte
  SoundCmd[2]=Command_Length
  SoundCmd[3]=cmd
  SoundCmd[4]=Acknowledge
  SoundCmd[5]=cmdp1
  SoundCmd[6]=cmdp2
  SoundCmd[7]=soundCheckSum.HighByte
  SoundCmd[8]=soundCheckSum.LowByte
  SoundCmd[9]=End_Byte
  RsOut Str SoundCmd

TimB


Rsout data
Sends the raw data

Rsout Dec data sends "data" converted to ASCII

RsOut Str SoundCmd
Sends the ASCII

When you say binary do you mean 010110101? If you want data as raw unformatted then its simple in a loop

index = 0
repeat
rsout SoundCmd[index]
inc index = 0
until index = arrayLen





trastikata

Just send the data as bytes. Assuming the array is a byte array:

For i = 0 to 9
  RsOut SoundCmd[i]   
Next

Trikkitt

Thanks - that is my next step to try.  It just seems a bit crazy to not be able to specify a byte array as the parameter to send and have it send that.  We know the array length, so why can't it just send it?  I'll play around with the above methods.  I think my worry is that too much gap between calls to the command could mess up serial data timing.

trastikata

Quote from: Trikkitt on Aug 07, 2021, 07:26 PMI think my worry is that too much gap between calls to the command could mess up serial data timing.

At 9600 bps you don't have to worry.  ;)

top204

#5
The Str modifier will send out all the raw bytes of an array if a length is not assigned to it. It will not convert to ASCII when transmitting or receiving using the Str modifier. The modifier's name was kept to give compatability with the Parallax stamp chips.

top204

#6
I wrote a code snippet for transmitting a byte array using a procedure a few weeks ago as well:

https://protoncompiler.com/index.php/topic,486.0.html

The procedure uses the HRsout command, but it can easily be changed to Rsout, or any other transmitting command.

Now that the compiler has procedures, the modifiers are required less and less, and creating a procedure to perform a task is much better because it has more control, and it can be adapted to perform specific tasks that may be required in a program.

With Async coms, timing is very important, so if you have control of the transmitter, make sure there is a gap between the bytes sent that allows the receiver to do things with them. Also, make sure you are running the receiving device at its highest speed, so it performs tasks a lot faster. Using interrupt driven receiver buffering will also make the program a lot more reliable and efficient because bytes will always be received by the USARTs, regardless of what the main program is doing.

charliecoutas

Does Rsout turn interrupts off for the duration of its transmission? If not then surely your interrupt activity will upset the timing of the Rsout command? (You said you are using the other hardware ports under interrupts.)

Charlie

top204

The RSout and RSin commands do not disable interrupts, so it is always important to find the timing of an interrupt and add the time to the Baud rate value.

I make a point of not interfering with interrupts with the commands if at all possible. It is up to the user to disable/enable them when required to do so.

charliecoutas

Thanks Les, that's what I thought. I had the same problem: both USARTs running under interrupts and I needed another RS232. SO I used RSout and the only way to be sure that the bit-bashed RSout would not get messed up was to disable interrupts during the time RSout was active.

Charlie

top204

#10
The only problem with that Charlie, is that while the interrupt is disabled, the USARTs might miss some data coming in, even with their 2 byte internal buffer. It depends on what length the data was being transmitted, and the Baud rate used.

For that mechanism, it would "now" be better to create a procedure with a loop for the amount of bytes being transmitted, and only disable the interrupts when the RSout command is transmitting a single byte, then re-enable the interrupts after the byte is transmitted. That way, the interrupt will only be disabled for a very short time span. To transmit with "modifiers", fill a String variable or a Byte array with what needs to be transmitted, and transmit each element of the String variable or array seperately until the length of the String or array is reached. That's where the Str$ function comes in very handy.

Whenever I use interrupts that can cause a time lag, I add the time to the RSout and RSin Baud declare. The same for other time critical software interfaces.

charliecoutas

To go back to Trikkitt's problem, I don't think it will work, for the reasons I just mentioned. I sorted mine out a long time ago, but this problem brought back memories. If he can transmit single bytes with ints disbaled then re-enabled, as Les suggested then it might be OK.

Trikkitt: do you follow what we are on about?

Charlie

Trikkitt

Quote from: charliecoutas on Aug 09, 2021, 09:29 AMTo go back to Trikkitt's problem, I don't think it will work, for the reasons I just mentioned. I sorted mine out a long time ago, but this problem brought back memories. If he can transmit single bytes with ints disbaled then re-enabled, as Les suggested then it might be OK.

Trikkitt: do you follow what we are on about?

Yes - that makes perfect sense.  Disable interrupts while the RSout command is running to avoid it impacting the timing of the byte transmission. The challenge of course is, of my two hardware interfaces one is running at 2400bps so not an issue, the other is running at 115200bps, so could have received 12 bytes in the time it takes to transmit one at 9600.  So if a message arrives during the RSOut I will lose it.  If I let it disrupt the RSOut timing then that may fail.  I'm hoping the 32Mhz and light weight interrupt routine might be enough not to damage the 9600bps timings too much.

Trikkitt

Quote from: top204 on Aug 08, 2021, 12:10 PMI wrote a code snippet for transmitting a byte array using a procedure a few weeks ago as well:

https://protoncompiler.com/index.php/topic,486.0.html

The procedure uses the HRsout command, but it can easily be changed to Rsout, or any other transmitting command.

Now that the compiler has procedures, the modifiers are required less and less, and creating a procedure to perform a task is much better because it has more control, and it can be adapted to perform specific tasks that may be required in a program.

Thanks - I'm yet to look at procedures.  I'm still on Proton with a dongle at the moment, and only really use Proton for the very occasional personal project.  Only found out about all the changes when I went to research an issue and found the forums had moved.

tumbleweed

If you could rearrange it sp that the 9600 and 115K use the hardware ports, then you could look at generating the 2400 in software using a timer intr. 2400 baud is roughly 416us/bit, so that would give you about 12us of slop (3%) to deal with the other incoming bytes. You could do the same with 9600, but the bit timing is a lot tighter.

charliecoutas

If possible, you could always move to a PIC with more USARTS. I know some have 4 and more USARTs.
I just tried to find some for you on Microchip's website but I find it even more confusing than it used to be!


tumbleweed

Quote from: charliecoutas on Aug 12, 2021, 02:59 PMIf possible, you could always move to a PIC with more USARTS.
That would be my suggestion too.

A software uart would be my absolute last choice... they're just too unreliable in my book.

keytapper

I striven for a month to discover I was doing wrong setting. I assumed that the default was normal, but is inverted. So I was leaving out the declarations for that.
My doubt is how the TX pin is set in idle state. I read the assembly, but I didn't noticed any output setup.
Ignorance comes with a cost

Trikkitt

Sadly this project is way too far down the line to switch PICs.  It is effectively reusing an old board that I've ton of kicking about to jerry rig something I only need to make 6 of.  End result I'm stuck with this PIC unless I have go back to the drawing board and design a new PCB!  So far in my testing the 9600 in software has worked pretty well.  At least enough that it hasn't caused the data to get scrambled.  Even in the worst case though, the 9600 data isn't essential and it just won't play an audio clip.  But so far it has been faultless.  I guess i'll find out when I test it in earnest next week!