PDA

View Full Version : Strings......and how to join them



gringobomba14
- 17th July 2008, 17:44
Hello all. So, I have learned more off this forum than I ever imagined (I now have a fully functional temperature/humidity controller, which I can send via FM RF about 100 metres using serin2/serout2, switch on humidifiers, switch on de-humidifiers, switch on heaters, coolers)...so now I need to know how to make a string of several different variables, I.E. out= A joined with B and joined with C. Am I making sense?

skimask
- 17th July 2008, 17:54
You have to do it the hard way...OR...
If you're savvy enough, you could define a large array, then split that array up into smaller arrays manually...OR...
If you're really savvy, you could define a string array at a certain ram location, then define a second array at a second ram location, define a third array at a third location, all locations being sequential (not neccessarily one after another, but in a sequence). Then using a little trick, you can access the whole array using the name of the first array. PBP doesn't check for the end of an array (no bounds checking) so if you try to get an index that's larger than one that is actually defined, you can 'run into' the next array.
For instance:
string var byte[16] $100
string2 var byte[16] $110
string3 var byte[16] $120
string4 var byte[16] $130
that'll put string at $100, string2 at $110, string3 at $120, string4 at $130, and so on...
You can get to all 3 strings by:
string[ whatever ]
To get to the 3rd byte of string4, position 51, would be:
string[ 51 ]
Of course this would only work with fixed length strings.
You could easily 'terminate' each individual string with a $00, like VB does, and could easily write a routine to put individual strings together into one main string.

I guess what it really boils down to is...What exactly are you trying to do? You're a bit vague...

gringobomba14
- 17th July 2008, 19:24
Really, all I want to do is take a constant i(2 bits) add a variable in t(3 bits) add another variable in h(3bits) and make it all one long(ish) variable of 8 bits, so I end up with string = iittthhh. I guess I could "join" them in the serout2 command (serout2,portpin,mode,i,t,h) but that didn't seem to work very well for me

skimask
- 17th July 2008, 19:39
Really, all I want to do is take a constant i(2 bits) add a variable in t(3 bits) add another variable in h(3bits) and make it all one long(ish) variable of 8 bits, so I end up with string = iittthhh. I guess I could "join" them in the serout2 command (serout2,portpin,mode,i,t,h) but that didn't seem to work very well for me
You might have wanted this intead of what you had:

SEROUT2 portpin, mode, [ ( ( i << 6 ) + ( t << 3 ) + h ) ]

The way you had it, all it would do would send out 3 different bytes of value corresponding to i, t, and h.

gringobomba14
- 17th July 2008, 23:00
Excellent call on the SEROUT. Good to know I can do that to join strings. I got this error though on the receiver....

ERROR: Macro SERIN2STR?WL not found in macro file.
ERROR: Macro HSEROUTSTR?W not found in macro file.

Which means I need an include file somewhere.......

skimask
- 18th July 2008, 02:44
Excellent call on the SEROUT. Good to know I can do that to join strings. I got this error though on the receiver....

ERROR: Macro SERIN2STR?WL not found in macro file.
ERROR: Macro HSEROUTSTR?W not found in macro file.

Which means I need an include file somewhere.......

Are you using PicBasic or PicBasicPro?

gringobomba14
- 18th July 2008, 07:08
PicBasicPro

skimask
- 18th July 2008, 13:40
PicBasicPro
Which version?
And what line exactly is causing your problem?

gringobomba14
- 18th July 2008, 20:03
That problem has gone. For future reference, I am using version 2.47. The problem I'm having now is this. I have perfect radio communications between 2 16F877A's, at both short and long range, but I'm not having much success transmitting and then receiving variables.

My TX line is :
SEROUT2 PORTc.2,16780,[((id<<6)+(rhtc/100<<3)+(temp/100))]

which seems not to be a problem

my RX line is

SERIN2 PORTc.4,16780,250,programstart,[str myvar\6]

but I don't get what I send. I'm sure there is a glaring error somewhere, but when I hserout myvar I get numbers, but not what I sent

skimask
- 18th July 2008, 20:39
My TX line is :
SEROUT2 PORTc.2,16780,[ ((id<<6) + (rhtc/100<<3) + (temp/100))]

which seems not to be a problem

my RX line is
SERIN2 PORTc.4,16780,250,programstart,[str myvar\6]
but I don't get what I send. I'm sure there is a glaring error somewhere, but when I hserout myvar I get numbers, but not what I sent

You're only sending one byte, but expecting to receive 6? How does that work?

And your SEROUT doesn't make a lot of sense...
You're shifting id up 6 bits, adding in a number that may or may not fit into those next 3 bits, and doing the same thing with the last number. What's up with that?

Maybe it would be best if you showed your code rather than your broken snippets.

gringobomba14
- 18th July 2008, 21:11
I got the SEROUT line from your posting(yesterday, 19:49), but all I really want to do is send an id (25 or 35) and a 4 digit temp or humidity reading, then receive same using the serout2/serin2 commands. When I send the command to the remote module it receives it perfectly as it is a constant number and sends what it is asked to....

receive: ' receive
portc.1 = 1 ' switch on port
pause 25 ' give radio 25 ms to slew
SERIN2 PORTC.0,16780,250,main,[command]
if command = 25 then goto tempsend
if command = 35 then goto humsend
goto main

When I send 25 it goes to tempsend, when I send 35 it goes to humsend.

My latest attempt to send what I want is as follows:
tempsend:
portc.1=0 ' Back to main
lcdout $fe,1,"tx t" ' send to lcd
portc.3=1 ' switch on tx
for c =0 to 4 ' start 4 pass loop
pause 150
SEROUT2 PORTc.2,16780,[temp]
PAUSE 100 ' Pause 100uS
next c ' next pass
portc.3=0 ' switch off tx
goto main ' Back to main

temp is a 4 digit number and comes from the SHT71 sensor and is displayed correctly on the LCD


The above is received with:

SERIN2 PORTc.4,16780,250,programstart,[str myvar\4]
HSEROUT ["A= ",dec myvar," B= ",#myvar," C= ",myvar," ",32,13,10] ' Display result
CLEAR ' Clear array

so I can have an idea what is being received and work out how to make it what I want

skimask
- 18th July 2008, 21:28
So, if you're sending it like this:
SEROUT2 PORTc.2,16780,[temp]
Why are you trying to receive it like this?
SERIN2 PORTc.4,16780,250,programstart,[str myvar\4]
Doesn't it make sense that the format for sending and receiving would probably be the same? It really wouldn't make a lot of sense to have 2 commands that perform the same function (albiet the opposite function) send and receive the same data in 2 completely different ways, does it?

How about trying some of this...Just try it and see what happens:

tempsend:
portc.1=0 : lcdout $fe,1,"tx t" : portc.3=1
for c =0 to 4
pause 150 How long does this pause?
SEROUT2 PORTc.2,16780,[temp]
PAUSE 100 ' Pause 100uS This doesn't pause for 100us...
next c ' next pass
portc.3=0 : goto main


SERIN2 PORTc.4 , 16780 , 250 , programstart , [ temp ]
HSEROUT ["A= ",dec temp," B= ",#temp," C= ",temp," ",32,13,10] ' Display result
'A = should be a formatted integer, B=should be a formatted integer, C=will probably be garbage
CLEAR ' Clear array


And another thing...you might have sync'ing issues. You've got a 250ms timeout on the SERIN2 in the RX code, and various pauses and such in the TX code. How often are the two actually going to be ready for each other?

gringobomba14
- 18th July 2008, 21:53
I did write uS when I meant mS, but no worries.
The synching issue isn't a problem, because the PIC on the PC sends a command out to the other PIC and it acts on that command. The other PIC is in receive mode straight after the command is sent waiting 250ms for something to come in.

On the code bit....
I expected 3638, I got 146. I expected 3640 or something close, and I get 224. The annoying thing is, I had this part working a few weeks ago, and I messed around with it, and now I can't remember how I done it. thats how I ended up messing around with the formats, and of course, sending a byte and getting a string....not a good way to make things work

ALTHOUGH, I have now found the error. It's not so much in the TX or RX, but in the definition of temp. I'm working on that now, so I will get back with a real update in the next hour or two

gringobomba14
- 18th July 2008, 22:30
I sent to the LCD display whats being sent by the radio, and I'm not getting what I'm sending. I'm sending 637 (that 6 came from nowhere by the way) and I'm receiving 236 or 224 or 3 or some other almost random number. Maybe time for bed and see what tomorrow brings. or half a stick of dynamite and a box of PIC's

skimask
- 19th July 2008, 00:22
I sent to the LCD display whats being sent by the radio,
WHOA! When did the RF come into the mix here?
Do a search on manchester encoding and come back when you get something written.

gringobomba14
- 22nd July 2008, 10:34
Ski, I spent yesterday and Sunday encoding my data with the Manchester coding, and it is a very bulky way of getting information from point A to B via RF. I did a lot of playing around and I found that if I send what I want at 4800 bps and inverted (mode 16752) or 2400 bps and inverted it will arrive fine EVERY TIME. HOWEVER, if you try and send the data NON-INVERTED it just arrives muddled and messed up. Here is the TX and RX code. There is no need for synching because the the temp/hum sender only sends the data when asked, and sends it individually.

(PC Based 16F877)

transmit: 'Send commands
let i=0 ' Set i to 0
for i = 0 to 1 ' 2 pass loop
portd.1=1 ' Switch on TX module
pause 125 ' wait 125 ms to slew TX
serout2 PORTd.0,16572,[25,25,25,25] ' send command to get Temp
pause 25 ' pause
next i ' Next pass
portd.1=0 ' switch off TX module
portc.3=1 ' switch on RX module
pause 113 ' pause to allow RX to slew
SERIN2 PORTc.4,16572,250,programstart,[STR temp\25\13] 'receive temp up to 25 bits, ending with char 13
HSEROUT [str temp\21,13,10,32,CR] ' display temp
clear ' clear array
pause 10000 ' wait 10 seconds
let i=0 ' set i to 0
for i = 0 to 1 ' start 2 pass loop
portd.1=1 ' switch on TX module
pause 125 ' allow time for TX module to switch on
serout2 PORTd.0,16572,[35,35,35,35] ' send command to get Humidity
pause 25 ' pause
next i ' next pass
portd.1=0 ' switch off TX module
portc.3=1 ' switch on RX module
pause 113 ' pause
SERIN2 PORTc.4,16572,250,programstart ,[STR hum\25\13] 'receive humidity up to 25 bits, ending with char 13
HSEROUT [" ",str hum\21,13,10,32,CR] ' Display result
CLEAR ' Clear array
pause 125 ' Pause
portc.3=0 ' switch off RX module
pause 10 ' Pause
goto programstart


(Temp / Humidity module)
receive: ' receive
portc.1 = 1 ' switch on port
pause 25
SERIN2 PORTC.0,16572,250,main,[command]
if command = 25 then goto tempsend
if command = 35 then goto humsend
goto main

'*********************** Send the Temperature *********************'

tempsend:
portc.1=0 :
portc.3=1
for c =0 to 2
pause 150 'pause 150 mS
SEROUT2 PORTc.2,16572,["**Temperature ",dec2(temp/100),".",dec1 (Temp),13]
PAUSE 100 ' Pause 100mS
next c ' next pass
portc.3=0 : goto main

'********************** Send the Humidity ***********************'
humsend:
portc.1=0 ' Back to main
portc.3=1 ' switch on tx
for c =0 to 2 ' start 4 pass loop
pause 150
SEROUT2 PORTc.2,16572,["**Humidity ",DEC2 (RHtc/10),".",DEC1 RHtc,13]
PAUSE 100 ' Pause 100uS
next c
portc.3=0
goto main ' next pass

skimask
- 22nd July 2008, 13:46
So is it working good then?

gringobomba14
- 22nd July 2008, 14:15
Yes. I have added the following to avoid any garbage(from my car alarm fob):

SERIN2 PORTc.4,16572,250,programstart,[wait("*"),STR temp\25\13]

so that unless the string begins with a * then nothing is received

and this on the TX side of the temp/hum module to help synching

SEROUT2 PORTc.2,16572,[$55,$55,$55,"**Temperature ",dec2(temp/100),".",dec1 (Temp),"+"]