The code that i posted in the zip file works to the very last line no errors and it transfers the correct data to the reciving board.A picture is posted below with the data that is transmited to the reciveing board.
you can see it expects a SINGLE byte as second parameter.
transmitting a string:
a string is a SEQUENCE of bytes terminated with a zero.
So for transmitting a string you have to write a method that works the same way as the str-method of any other serial driver like f.e. fullduplexserial
PUB str(stringptr)
'' Send zero terminated string that starts at the stringptr memory address
repeat strsize(stringptr)
tx(byte[noparse][[/noparse]stringptr++])
additional you have to take into acccount that you have a defined packetsize.
So you have to check how many bytes you in the string and if the string is longer than your packetsize
you have to transmit this part and then call send. And then do the rest of the string.
Or you increase the packetsize to the maximum length of the string and maybe cutoff bytes of strings that are still longer.
Without seeing the RECEIVING code I can not say what you have to change there to receive characters.
I only can guess that the receiving-code uses a "DEC"-method to show the received bytevalues as decimal values instead as ASCII-characters
So like always: best thing is to include REALLY ALL *.SPIN-files to a sposting.
ok i have added a string function to my code but i can not seem to get the text to transmit i had it workibg on my debug screen but when i sent it to the reciver board i get all 0 in my debug window..
Rx stands for RECEIVE.
Where is the method that does Tx? (which stands for TRANSMIT) ?
obviously you should be more careful than just open the next best *.spin-file looking for "str" and do a cut & paste.
YOU have to understand the code you are using.
Your demoprogram defines a string in the datsection and then does a call to RECEIVE a string. Where is the code that does FILL the buffer with the string?
The code does exactly what you have programmed. Wait for a string to be received until delimiter is received and then send an empty buffer
You seem to have still NOT enough experienced the fact "if you do it SUPERFAST the progress of a project becomes SUPERSLOW"
that you would change to a developing style of working careful and exactly.
Alright now. I am waking up the dead horse so he can be beaten some more.
I have 2 433MHz RF Transceiver modules,. 1 Pro Dev Board, 1 Prop Educ Kit Board, 1 BS2 Homework Board on a Boe-Bot
My goal is to use my PDB as a remote controller for the Boe-Bot using the transceivers.
I am a long way from that goal because I can't seem to follow the programming in the FullDuplexSerial spin file well enough to understand it and put it to use for me.
I have taken that program and went line by line looking up each and every command and operator in the Propeller Manual so I could learn the hows and whys of it.
I have learned much in the process but still cannot follow the flow of the variables in that thing. I ran Beau's transceiver program and it works just fine between my
2 propeller controllers. (Thanks for the effort Beau!) My problem is that I just want to know the very simple "How To" of sending data. For example:
My pins (5, 6, & 7) are connected to transceiver module just as Beau showed earlier in this thread.
How do I simply (in 2 or 3 commands) set my module to transmit.
Issue a single wake-up or sync call.
Transmit my info.
Set my module back to listen.
Using SPIN as my language.
As shown in the picture below, they accomplished what I am after with PBasic. Can someone translate this to SPIN for me.
I don't want all the calls to other subroutines and variables. I just want to be able to use exact commands like ' dira~~ ' and sent a piece of data.
This was difficult to try and explain what I am wanting, but I hope someone will get it.
~Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
I have a certain way of explaining and I want to tell you how my way works:
YOUR brain has to learn it - not mine. You already know some things about programming
Some of your imaginations about how the commands work are right some are wrong. Some of them you don't know YET
No MY way is:
first step: YOU make a suggestion how YOU think it works.
second step: I look at your suggestion and give you feedback about it.
The very important DIFFERENCE of that way is: that wrong imaginations about how commands work were discovered and can be corrected.
showing you a complete solution makes you hurry over it and getting messed up in complicated code without understanding it.
You start in small steps
For transmit and receive you have to set the T/R-input of the transmitter.
From your PBASIC-example I can see you have to set the T/R-line high for transmitting
post YOUR suggestion how to set the propeller-IO-pin No 5 high.
Everybody else is free to answer you whatever she/he likes. From me you are only getting an answer if YOU
posted YOUR suggestion.
For posting code use the commands "[noparse][[/noparse] code ] [noparse][[/noparse] / code ] WITHOUT the spaces.
This makes the code look like this
fixedwidth font to keep indentions seeable
To avoid the font getting big INSERT spaces after and before each square-bracket
" dira [noparse][[/noparse] 5 ] "
"<space>dira<space>[noparse][[/noparse]<space>5<space>]"
without spaces this forumsoftware misunderstands the digits as change-font-command and eats up the digits
I will post my code in picture form because I believe it's much easier to view. If it gets too long, we'll do something different.
You'll see in my code that I haven't gotten very far. The reasons are as follows:
- I don't know the equivalent set of commands to accomplish a SEROUT in SPIN language
- I don't know how to set a baud rate for an OUTA command
- I don't know how to place a specific character in an OUTA command
My understanding of what my code does at this point is:
- Sets the transceiver to transmit mode by raising TX-RX pin to high
- Sends a full 3.3 volt, 80 MHz, signal lasting 1000 repetitions to transceiver data pin
That's my level of understanding...When I make the output of a pin go high, I am assuming it gets full voltage and the full 80 MHz clock frequency applied to it.
I'm also assuming that this goes out as a square wave. I believe that this is just a high pulse as I have got it coded and think it probably cannot be recognized
by another transceiver because the frequency is too high.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
If you set an output-pin to high it stays high until you set it to low. It is NOT a squarewave it stays ALWAYS high until you set the pin low.
There is a second situation where the IO-state of a pin changes. If your code terminates completely because there are no more commands to execute
the IO-state is resetted to input.
example
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
PUB Main
dira[noparse][[/noparse]0] := 1 'set IO-direction to output
outa[noparse][[/noparse]0] := 1 'set IO-pin to high
waitcnt(ClkFreq * 3 + cnt) 'wait for 3 seconds
'after this command has been executed the cog stops and all IO-pins
'are resetted to input
A high-signal means 3.3V ALL the time
A low signal means 0.0V all the time
A squarewave means that the voltage-level is alternating between 3.3V and 0.0V at a certain frequency.
This means a squarewave can ONLY be created by switching the pin low-high-low-high-low-high....
which means the voltagelevel switches between 3.3V-0.0V-3.3V-0.0V-3.3V-0.0V-3.3V....
The PBasic command
PULSOUT 0,1200
creates ONE single pulse low-high-low
this means the logical state of the data-pin has to change at least one time low-high-low to sync the receiver
In SPIN there is NO exact equivalent to the PBASIC-command serout.
The PBASIC-command
SPIN works different. SPIN contains a basic set of simple commands.
For any kind of more complex commands or high sophisticated commands you build these more complex commands by combining the basic commands in a method
The predefined objects are nothing else but complex commands builded by combining basic SPIN-commands.
In the propellermanual you will only find the basic commands like dira, outa, repeat, if, case etc.
The PBASIC-command sends a number of bytes as a serial bitstream at a certain baudrate.
Now in SPIN if you use the FullDuplexSerial-object (which I recommend) you have a method called "tx" which can send ONE single byte
There are several other methods to send more than one single byte and these methods are based on the method "tx".
This means the method for sending a string like "ABC" uses the method "tx" several times send the byte-SEQUENCE "A" "B", "C".
FullDuplexSerial is an end product. I don't necessarily want to use it and move on, I want to learn how it works. The fact that it is written in both
SPIN and Assembly is keeping me from following it's flow to see exactly how it is doing what it's doing. I don't care to try and learn assembly at the
same time that I am trying to learn the SPIN language.
I want to know:
- How to initiate contact between transceivers.
- How to convert a command or text into bits and/or bytes.
- How to send these in serial form.
- How to receive these in serial form.
- How to convert back to a command or text.
Basically, I am asking for the tutorship from someone who knows how to perform these functions in SPIN. Believe it or not, I actually want to learn the how and why.
I'm not looking to just jump past this coding step by using someone else's work so that I can continue my project. I want to learn it.
Anyone that would like to help me out would sure be appreciated. I know it's no one's job to teach me, I am just hoping there are those that may be willing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
You can use the Simple_Serial object instead of FullDuplexSerial. Simple_Serial is written completely in Spin and is much simpler to understand. It can send and receive (half duplex only) at speeds up to 19.2KBaud with an 80MHz clock and it's not buffered. You could use a 2nd cog to make a Spin-only buffered receive routine if you want. The 433MHz receiver / transmitter are half duplex only, so they'd work fine with the capabilities of Simple_Serial.
I wrote 'nonZero-value' as every expression that results in a value <> 0 is interpreted as TRUE
every expression that results in zero is interpreted as FALSE
now if you look at the value of variable rxOkay after executing
rxOkay := rxPin > -1
the value of rxOkay will be -1. Which is a NON-zero value and is interpreted as true
other examples:
if 5
looks very short but is a valid "condition" that is ALWAYS true as "5" is a non-zero value
if -3
looks very short but is a valid "condition" that is ALWAYS true as "-3" is a non-zero value
if -1
looks very short but is a valid "condition" that is ALWAYS true as "-1" is a non-zero value
if (3-3)
looks very short but is a valid "condition" that is ALWAYS FALSE as "3-3" results in ZERO
this means every logical operation that results in true results in integer-value -1
every logical operation that results in FALSE results in integervalue 0
best regards
Stefan
Post Edited (StefanL38) : 1/24/2010 5:04:12 AM GMT
These are the only two incidences of rxPin and txPin in the Simple Serial Program. Neither variable were specified before this and so I am assuming
they both have a value of zero. Is that correct?
Now, the sin and sout variables. I have looked in the manual and so, have made the assertion that it is a bitwise AND function that AND's rxPin with $1F.
I understand the operation. I just don't know where the values are coming from. As before, I am assuming rxPin to be equal to zero or %00000000. I also have
figured out that $1F represents a memory location. Where they came up with it is what I don't know. It isn't used anywhere else in the program so I have nothing else
to compare it to. I know sin and sout are pin numbers later used for data transfer but, I don't know how this part of code is configuring it.
Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
eiplanner said...
These are the only two incidences of rxPin and txPin in the Simple Serial Program. Neither variable were specified before this and so I am assuming
they both have a value of zero. Is that correct?
Not quite. They are input parameters to the public init method. So they will be what the caller passes them in as.
eiplanner said...
Now, the sin and sout variables. I have looked in the manual and so, have made the assertion that it is a bitwise AND function that AND's rxPin with $1F.
I understand the operation. I just don't know where the values are coming from. As before, I am assuming rxPin to be equal to zero or %00000000. I also have
figured out that $1F represents a memory location.
What makes you think that's a memory location? It's just a value in hex notation (31 in this case). The prop has 32 I/O pins numbered from 0..31. To get rid of out of range values (e.g. 42) the value is masked, mod 32. As the latter is a power of two this can be conveniently written as & (32-1). That's all there is to it.
OK, I get the input parameters. But aren't they still just treated as variables?
I'm slow sometimes, but eventually the light does come on.
Please elaborate on the hex notation part because I am not following. Just so you aren't thinking that I just pulled it out of a hat, I put in "$1F" in the
pdf Prop Manual and it came up with info concerning memory locations. That's where it came from so I just made the assumption. Why does this have to be
ANDed with rxPin? Does SPIN perform the AND with the value of zero or does it use %00000000? That's what I'm not getting. Why not simply assign a pin #?
Thanks for patience.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
PUB init(rxPin, txPin, baud): Okay
finalize ' clean-up if restart
rxOkay := rxPin > -1 ' receiving?
txOkay := txPin > -1 ' transmitting?
sin := rxPin & $1F ' set rx pin
sout := txPin & $1F ' set tx pin
inverted := baud < 0 ' set inverted flag
bitTime := clkfreq / ||baud ' calculate serial bit time
return rxOkay | TxOkay
the codeline
PUB init(rxPin, txPin, baud): Okay
defines: "HERE Starts the DEFINITION of a subroutine"
when ever you USE the definition you code
init(5,6,9600)
where 5 means IO-pin-number used as rxpin
where 6 means IO-pin-number used as txpin
baudrate is 9600 baud
The values of rxPin and TxPin are defined at the CALL of the subroutine Init
and the CALL of Init configures it.
once again CALL of subroutine Init:
init(5,6,9600)
DEFINITION of subroutine Init
PUB init(rxPin, txPin, baud): Okay
finalize ' clean-up if restart
rxOkay := rxPin > -1 ' receiving?
txOkay := txPin > -1 ' transmitting?
sin := rxPin & $1F ' set rx pin
sout := txPin & $1F ' set tx pin
inverted := baud < 0 ' set inverted flag
bitTime := clkfreq / ||baud ' calculate serial bit time
return rxOkay | TxOkay
there is no EXACT equivalent in PBASIC to this
a more or less equivalent in PBASIC is if you code a subroutine with label "Init" (which is equivalent to the definition
and then somewhere else in the code write
gosub Init
In PBASIC you can't add parameters to a gosub
gosub LabelName - that's all
In SPIN you can add parameters to the subroutines
This is the big difference between PBASIC and SPIN
In PBASIC you have a lot of high sophistiscated, predefined commands like serout, shiftin etc. but you CAN'T change the details of these commands
In SPIN you have a much smaller and simpler set of predefined elementary commands like "if" "repeat" ":=" "case" "PUB" "return"
EVERYTHING in SPIN is build out of this elementary commands. This means YOU as the user can program command-extensions in whatever way you like
If you would like to have a command "Square" you just define it
PUB Square (x)
result := x * x
and wherever you need the Square of a number you call the new command
y := square(2)
and y will contain the value 4
MyVar4 := 3
MyVar23 := Square(MyVar4)
and MyVar23 will contain the value 9
Now if you need a customized method that calculate values X^2 - 17 YOU define it
PUB MyCustomized_method (x)
result := x * x - 17
and wherever you need values to be calculated you CALL your selfdefined method
K := MyCustomized_method (5)
$1F is a RAM-location but in this case it is simply a VALUE
only the numbers 0..31 are valid IO-Pin numbers.
The bitwise logical and with value $1F zeros all higher bits
imagine somebody calls method init with this values
init(67,17,9600)
the number 67 is NOT a valid IO-pin-number
the operation 67 & $1F as binary values
76543210
decimal 67 = %01000011
hexadecimal $1F = %00011111
result = %00000011 = decimal 3 a valid IO-pin number
cuts down the value to a valid IO-pin-number
if this is senseful can be discussed
best regards
Stefan
Post Edited (StefanL38) : 1/24/2010 5:47:04 AM GMT
$1F is the same as %11111 is the same as 31. This is a mask for the and operation ("&"). It restricts the value of sin (from rxPin) and sout (from txPin) to the range 0-31 which is the allowed range for I/O pin numbers.
Excellent! Thank you Stefan & Mike very much for the clear-up. Thanks greatly for the elaboration Stefan on how to define my own commands.
The light inside went on very brightly when you explained the Call and initial values routines. I get all of that now.
I know I am asking a lot of everyone's time in this, and I greatly appreciate it.
My lack of understanding in the process seems to be narrowing down to sections of the code that have multiple operators or functions in one line.
I've been studying each individual operator in the manual as I come across them but the manual doesn't cover too much of their uses in line with each
other. So, I am still working at it.
In this example I am not quite sure why baud < 0 is there, I am thinking it has something to do with inverted send & receive signals which I haven't got to yet.
I understand the bitTime variable. And, I am thinking the return value is an OR funtion between rxOkay and txOkay. If either one is true, it's value is returned
into the Okay variable.
Good, Bad, or Ugly?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
The baud parameter also indicates whether the serial signal is normal (baud > 0) or inverted (baud < 0) just like it's stated in the comments.
The return value is false if neither rxOkay is true nor txOkay is true. It's possible for one of these to be false (if the receive pin isn't used or the transmit pin isn't used), but both can't be false.
The manual does cover multiple operators in an expression. Look at the chapters on Operators in the Propeller Manual. This gives a table (4-10) with the operator precedence. This indicates which operators in an expression are evaluated first. This precedence can be overwritten by the use of parentheses. Notice that unary operators (except for NOT) take precedence over all others.
Post Edited (Mike Green) : 1/24/2010 6:20:23 AM GMT
So if baud is negative, inverted holds a value of -1 otherwise it will hold a value of zero.
Now this:
PUB finalize
{{Call this method after final use of object to release transmit pin.}}
if txOkay ' if tx enabled
dira[noparse][[/noparse]sout]~ ' float tx pin
rxOkay := txOkay := false
PUB rx: rxByte | t
{{ Receive a byte; blocks caller until byte received. }}
if rxOkay
dira[noparse][[/noparse]sin]~ ' make rx pin an input
waitpeq(inverted & |< sin, |< sin, 0) ' wait for start bit
t := cnt + bitTime >> 1 ' sync + 1/2 bit
repeat 8
waitcnt(t += bitTime) ' wait for middle of bit
rxByte := ina[noparse][[/noparse]sin] << 7 | rxByte >> 1 ' sample bit
waitcnt(t + bitTime) ' allow for stop bit
rxByte := (rxByte ^ inverted) & $FF ' adjust for mode and strip off high bits
I completely follow the finalize method. It simply resets everything.
My next roadblock is the inverted inside the waitpeq command line . After getting your answer on the first part, I am making another assumption; if BAUD was
negative, then this command line is waiting for the pin to go low. If BAUD was positive, then it's waiting for the pin to go high.
I don't understand the sync plus 1/2 bit line.
Or the rxByte line.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
waitpeq waits for the transistion of the pin-state
transistion means it waits for the moment when the logical state changes from low to high
or waits for the moment when the logical state changes from high to low (in inverted mode)
Now without waiting half the bittime the sampling of the other bits would be done right in the moment of the transistion
then you are in danger that some bits that should be a 1 are still sampled as a 0 or vice versa.
If you wait for half the bittime (=timeperiod that the bitvalue is valid) you ae not around the transistion but right in the middle of the pulse
where everything is clear stable.
cnt is the SYSTEMvariable of the FREE running counter. As a systemvariable you don't have to declare it it's already there and written bolded
bitTime >> 1 makes ONE bitshifting to the right. For binary numbers this is the same as dividing by 2
examples
decimal 2 binary %00000010
shift on ebit to right %%0000001 result decimal 1
decimal 16 binary %00010000
shift one bit to right %00001000 result decimal 8
decimal 24 binary %00011000
shift one bit to right %00001100 result decimal 12 (8+4)
of course for odd numbers the ",5" is truncated
now t contains a value actual systemvariable cnt + some time in the future
in waitcnt(t +=bitTime)
the "+= BitTime" sets the value of t more ahead into the future.
the += operator does the addition and as the "+" is in front of the "=" immediatly stores the RESULT into t
so t+=BitTime is s hort form of t := t + BitTime
this means waitcnt(t+= BitTime) waits until the systemcounter matches the value of t
Read the Wikipedia articles on RS232 signalling. That will give you the information on signal levels.
Most logic operates at 0V/5V or, these days, 0V/3.3V. There has to be level shifting circuitry to interface to RS232 levels. Many interface circuits invert the signal just because of how they work. The system designer can add a logic inverter or change the way the UART works to invert the signal there and save a couple of parts. If you don't use RS232 and use straight logic level signalling to, say, a USB to logic level serial adapter, the signal may be inverted or not inverted depending on how the adapter is designed. It's useful to have a software serial driver that can handle (and be configured for) either case.
Below I have pictures of the program I ran and the result it gave me in the serial terminal.
It's the complete program shown other than the called objects. I cannot get a good result no matter how I have
tried to call it. I tried calling tx, rx, str, strtobin, bin, hex and any others in the fullduplexserialplus list and all I get
is garbage out.
It's basically square one and I don't think it appears all that complicated, but I am having no luck.
Can someone please assist me with this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
You didn't say what you're trying to do. Your program is probably doing what you wrote which is to transmit the byte 20 times found in the least significant 8 bits of the address of Tester (whatever that is).
What do you want to send?
It's always more helpful for you to describe what you're trying to do in general descriptive terms. You can do it in your message or you can include the information as comments in your program or program fragment.
Sorry Mike, I was trying to find the value of the Tester variable. One thing I didn't understand while trying to figure out how the simple serial
was receiving it's data was the variable called inverted. I just wanted to make a short quick program to mimic that part of the code so I could
find out what was actually happening in the inverted := baud < 0 statement. I know by their comments that it is supposed to be setting
the inverted flag, but I really don't know what that means or what it actually does. They later use the inverted variable in the waitpeq command.
I assume this is to invert the signal if needed. I just don't know how or why it does this. I also am not exactly sure how or which method to
call from the fullduplexserial object to show me this result.
I completely understand that what goes in comes out in programming. My problem isn't that I am expecting a certain result. My problem is that
I am simply guessing on the programming end and hoping to come across my result. Sort of like trying to find the square root of a number by
picking two arbitrary numbers, multiplying them, viewing the result, and narrowing them down until you get the answer. Believe me, I did not just
try this once and gave up. I have been at it all weekend. There's approximately 12 lines of programming in the simple serial file that accomplish
the data receive function and I only understand about half of them. So, I have spent many hours trying to decipher each piece of the program.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ It's not the size of the dog in the fight, but the size of the fight in the dog.
Comments
Even if the year is just 3 days old. Same procedure as every year.
Provide more information.
In the procedure of testing the several parts. What is working and what not ?
What do you receive? Nothing at all? Rubbish? two bytes?
best regards
Stefan
happy new year to everyone......
The code that i posted in the zip file works to the very last line no errors and it transfers the correct data to the reciving board.A picture is posted below with the data that is transmited to the reciveing board.
if you take a look into the method PutTX
you can see it expects a SINGLE byte as second parameter.
transmitting a string:
a string is a SEQUENCE of bytes terminated with a zero.
So for transmitting a string you have to write a method that works the same way as the str-method of any other serial driver like f.e. fullduplexserial
additional you have to take into acccount that you have a defined packetsize.
So you have to check how many bytes you in the string and if the string is longer than your packetsize
you have to transmit this part and then call send. And then do the rest of the string.
Or you increase the packetsize to the maximum length of the string and maybe cutoff bytes of strings that are still longer.
Without seeing the RECEIVING code I can not say what you have to change there to receive characters.
I only can guess that the receiving-code uses a "DEC"-method to show the received bytevalues as decimal values instead as ASCII-characters
So like always: best thing is to include REALLY ALL *.SPIN-files to a sposting.
best regards
Stefan
FULL CODE ATTACHED
Rx stands for RECEIVE.
Where is the method that does Tx? (which stands for TRANSMIT) ?
obviously you should be more careful than just open the next best *.spin-file looking for "str" and do a cut & paste.
YOU have to understand the code you are using.
Your demoprogram defines a string in the datsection and then does a call to RECEIVE a string. Where is the code that does FILL the buffer with the string?
The code does exactly what you have programmed. Wait for a string to be received until delimiter is received and then send an empty buffer
You seem to have still NOT enough experienced the fact "if you do it SUPERFAST the progress of a project becomes SUPERSLOW"
that you would change to a developing style of working careful and exactly.
best regards
Stefan
Post Edited (StefanL38) : 1/7/2010 9:44:54 AM GMT
I have 2 433MHz RF Transceiver modules,. 1 Pro Dev Board, 1 Prop Educ Kit Board, 1 BS2 Homework Board on a Boe-Bot
My goal is to use my PDB as a remote controller for the Boe-Bot using the transceivers.
I am a long way from that goal because I can't seem to follow the programming in the FullDuplexSerial spin file well enough to understand it and put it to use for me.
I have taken that program and went line by line looking up each and every command and operator in the Propeller Manual so I could learn the hows and whys of it.
I have learned much in the process but still cannot follow the flow of the variables in that thing. I ran Beau's transceiver program and it works just fine between my
2 propeller controllers. (Thanks for the effort Beau!) My problem is that I just want to know the very simple "How To" of sending data. For example:
My pins (5, 6, & 7) are connected to transceiver module just as Beau showed earlier in this thread.
How do I simply (in 2 or 3 commands) set my module to transmit.
Issue a single wake-up or sync call.
Transmit my info.
Set my module back to listen.
Using SPIN as my language.
As shown in the picture below, they accomplished what I am after with PBasic. Can someone translate this to SPIN for me.
I don't want all the calls to other subroutines and variables. I just want to be able to use exact commands like ' dira~~ ' and sent a piece of data.
This was difficult to try and explain what I am wanting, but I hope someone will get it.
~Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
dira~~ (no variables, just straight commands)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
By the way, a 5 inside of square brackets will make your font very big.....lol
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
I have a certain way of explaining and I want to tell you how my way works:
YOUR brain has to learn it - not mine. You already know some things about programming
Some of your imaginations about how the commands work are right some are wrong. Some of them you don't know YET
No MY way is:
first step: YOU make a suggestion how YOU think it works.
second step: I look at your suggestion and give you feedback about it.
The very important DIFFERENCE of that way is: that wrong imaginations about how commands work were discovered and can be corrected.
showing you a complete solution makes you hurry over it and getting messed up in complicated code without understanding it.
You start in small steps
For transmit and receive you have to set the T/R-input of the transmitter.
From your PBASIC-example I can see you have to set the T/R-line high for transmitting
post YOUR suggestion how to set the propeller-IO-pin No 5 high.
Everybody else is free to answer you whatever she/he likes. From me you are only getting an answer if YOU
posted YOUR suggestion.
For posting code use the commands "[noparse][[/noparse] code ] [noparse][[/noparse] / code ] WITHOUT the spaces.
This makes the code look like this
To avoid the font getting big INSERT spaces after and before each square-bracket
" dira [noparse][[/noparse] 5 ] "
"<space>dira<space>[noparse][[/noparse]<space>5<space>]"
without spaces this forumsoftware misunderstands the digits as change-font-command and eats up the digits
best regards
Stefan
I will post my code in picture form because I believe it's much easier to view. If it gets too long, we'll do something different.
You'll see in my code that I haven't gotten very far. The reasons are as follows:
- I don't know the equivalent set of commands to accomplish a SEROUT in SPIN language
- I don't know how to set a baud rate for an OUTA command
- I don't know how to place a specific character in an OUTA command
My understanding of what my code does at this point is:
- Sets the transceiver to transmit mode by raising TX-RX pin to high
- Sends a full 3.3 volt, 80 MHz, signal lasting 1000 repetitions to transceiver data pin
That's my level of understanding...When I make the output of a pin go high, I am assuming it gets full voltage and the full 80 MHz clock frequency applied to it.
I'm also assuming that this goes out as a square wave. I believe that this is just a high pulse as I have got it coded and think it probably cannot be recognized
by another transceiver because the frequency is too high.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
If you set an output-pin to high it stays high until you set it to low. It is NOT a squarewave it stays ALWAYS high until you set the pin low.
There is a second situation where the IO-state of a pin changes. If your code terminates completely because there are no more commands to execute
the IO-state is resetted to input.
example
A high-signal means 3.3V ALL the time
A low signal means 0.0V all the time
A squarewave means that the voltage-level is alternating between 3.3V and 0.0V at a certain frequency.
This means a squarewave can ONLY be created by switching the pin low-high-low-high-low-high....
which means the voltagelevel switches between 3.3V-0.0V-3.3V-0.0V-3.3V-0.0V-3.3V....
The PBasic command
creates ONE single pulse low-high-low
this means the logical state of the data-pin has to change at least one time low-high-low to sync the receiver
In SPIN there is NO exact equivalent to the PBASIC-command serout.
The PBASIC-command
serout performs sending 5 bytes.
SPIN works different. SPIN contains a basic set of simple commands.
For any kind of more complex commands or high sophisticated commands you build these more complex commands by combining the basic commands in a method
The predefined objects are nothing else but complex commands builded by combining basic SPIN-commands.
In the propellermanual you will only find the basic commands like dira, outa, repeat, if, case etc.
The PBASIC-command sends a number of bytes as a serial bitstream at a certain baudrate.
Now in SPIN if you use the FullDuplexSerial-object (which I recommend) you have a method called "tx" which can send ONE single byte
There are several other methods to send more than one single byte and these methods are based on the method "tx".
This means the method for sending a string like "ABC" uses the method "tx" several times send the byte-SEQUENCE "A" "B", "C".
best regards
Stefan
SPIN and Assembly is keeping me from following it's flow to see exactly how it is doing what it's doing. I don't care to try and learn assembly at the
same time that I am trying to learn the SPIN language.
I want to know:
- How to initiate contact between transceivers.
- How to convert a command or text into bits and/or bytes.
- How to send these in serial form.
- How to receive these in serial form.
- How to convert back to a command or text.
Basically, I am asking for the tutorship from someone who knows how to perform these functions in SPIN. Believe it or not, I actually want to learn the how and why.
I'm not looking to just jump past this coding step by using someone else's work so that I can continue my project. I want to learn it.
Anyone that would like to help me out would sure be appreciated. I know it's no one's job to teach me, I am just hoping there are those that may be willing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
This is a line of code from the attached Simple Serial:
Besides the fact that it's not in it's simplest form, is the below written code accomplishing the same exact thing?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
rxPin and TxPin are parameters of the method init specifying the IO-pin-numbers (which can be 0..31)
so the codeline means:
I wrote 'nonZero-value' as every expression that results in a value <> 0 is interpreted as TRUE
every expression that results in zero is interpreted as FALSE
now if you look at the value of variable rxOkay after executing
rxOkay := rxPin > -1
the value of rxOkay will be -1. Which is a NON-zero value and is interpreted as true
other examples:
looks very short but is a valid "condition" that is ALWAYS true as "5" is a non-zero value
looks very short but is a valid "condition" that is ALWAYS true as "-3" is a non-zero value
looks very short but is a valid "condition" that is ALWAYS true as "-1" is a non-zero value
looks very short but is a valid "condition" that is ALWAYS FALSE as "3-3" results in ZERO
this means every logical operation that results in true results in integer-value -1
every logical operation that results in FALSE results in integervalue 0
best regards
Stefan
Post Edited (StefanL38) : 1/24/2010 5:04:12 AM GMT
These are the only two incidences of rxPin and txPin in the Simple Serial Program. Neither variable were specified before this and so I am assuming
they both have a value of zero. Is that correct?
Now, the sin and sout variables. I have looked in the manual and so, have made the assertion that it is a bitwise AND function that AND's rxPin with $1F.
I understand the operation. I just don't know where the values are coming from. As before, I am assuming rxPin to be equal to zero or %00000000. I also have
figured out that $1F represents a memory location. Where they came up with it is what I don't know. It isn't used anywhere else in the program so I have nothing else
to compare it to. I know sin and sout are pin numbers later used for data transfer but, I don't know how this part of code is configuring it.
Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
What makes you think that's a memory location? It's just a value in hex notation (31 in this case). The prop has 32 I/O pins numbered from 0..31. To get rid of out of range values (e.g. 42) the value is masked, mod 32. As the latter is a power of two this can be conveniently written as & (32-1). That's all there is to it.
HTH
I'm slow sometimes, but eventually the light does come on.
Please elaborate on the hex notation part because I am not following. Just so you aren't thinking that I just pulled it out of a hat, I put in "$1F" in the
pdf Prop Manual and it came up with info concerning memory locations. That's where it came from so I just made the assumption. Why does this have to be
ANDed with rxPin? Does SPIN perform the AND with the value of zero or does it use %00000000? That's what I'm not getting. Why not simply assign a pin #?
Thanks for patience.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
this piece of code DEFINES the command init
the codeline
defines: "HERE Starts the DEFINITION of a subroutine"
when ever you USE the definition you code
where 5 means IO-pin-number used as rxpin
where 6 means IO-pin-number used as txpin
baudrate is 9600 baud
The values of rxPin and TxPin are defined at the CALL of the subroutine Init
and the CALL of Init configures it.
once again CALL of subroutine Init:
DEFINITION of subroutine Init
there is no EXACT equivalent in PBASIC to this
a more or less equivalent in PBASIC is if you code a subroutine with label "Init" (which is equivalent to the definition
and then somewhere else in the code write
In PBASIC you can't add parameters to a gosub
gosub LabelName - that's all
In SPIN you can add parameters to the subroutines
This is the big difference between PBASIC and SPIN
In PBASIC you have a lot of high sophistiscated, predefined commands like serout, shiftin etc. but you CAN'T change the details of these commands
In SPIN you have a much smaller and simpler set of predefined elementary commands like "if" "repeat" ":=" "case" "PUB" "return"
EVERYTHING in SPIN is build out of this elementary commands. This means YOU as the user can program command-extensions in whatever way you like
If you would like to have a command "Square" you just define it
and wherever you need the Square of a number you call the new command
and y will contain the value 4
and MyVar23 will contain the value 9
Now if you need a customized method that calculate values X^2 - 17 YOU define it
and wherever you need values to be calculated you CALL your selfdefined method
$1F is a RAM-location but in this case it is simply a VALUE
only the numbers 0..31 are valid IO-Pin numbers.
The bitwise logical and with value $1F zeros all higher bits
imagine somebody calls method init with this values
the number 67 is NOT a valid IO-pin-number
the operation 67 & $1F as binary values
cuts down the value to a valid IO-pin-number
if this is senseful can be discussed
best regards
Stefan
Post Edited (StefanL38) : 1/24/2010 5:47:04 AM GMT
you nailed it down to the point
best regards
Stefan
The light inside went on very brightly when you explained the Call and initial values routines. I get all of that now.
I know I am asking a lot of everyone's time in this, and I greatly appreciate it.
My lack of understanding in the process seems to be narrowing down to sections of the code that have multiple operators or functions in one line.
I've been studying each individual operator in the manual as I come across them but the manual doesn't cover too much of their uses in line with each
other. So, I am still working at it.
In this example I am not quite sure why baud < 0 is there, I am thinking it has something to do with inverted send & receive signals which I haven't got to yet.
I understand the bitTime variable. And, I am thinking the return value is an OR funtion between rxOkay and txOkay. If either one is true, it's value is returned
into the Okay variable.
Good, Bad, or Ugly?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
The return value is false if neither rxOkay is true nor txOkay is true. It's possible for one of these to be false (if the receive pin isn't used or the transmit pin isn't used), but both can't be false.
The manual does cover multiple operators in an expression. Look at the chapters on Operators in the Propeller Manual. This gives a table (4-10) with the operator precedence. This indicates which operators in an expression are evaluated first. This precedence can be overwritten by the use of parentheses. Notice that unary operators (except for NOT) take precedence over all others.
Post Edited (Mike Green) : 1/24/2010 6:20:23 AM GMT
Now this:
I completely follow the finalize method. It simply resets everything.
My next roadblock is the inverted inside the waitpeq command line . After getting your answer on the first part, I am making another assumption; if BAUD was
negative, then this command line is waiting for the pin to go low. If BAUD was positive, then it's waiting for the pin to go high.
I don't understand the sync plus 1/2 bit line.
Or the rxByte line.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
transistion means it waits for the moment when the logical state changes from low to high
or waits for the moment when the logical state changes from high to low (in inverted mode)
Now without waiting half the bittime the sampling of the other bits would be done right in the moment of the transistion
then you are in danger that some bits that should be a 1 are still sampled as a 0 or vice versa.
If you wait for half the bittime (=timeperiod that the bitvalue is valid) you ae not around the transistion but right in the middle of the pulse
where everything is clear stable.
cnt is the SYSTEMvariable of the FREE running counter. As a systemvariable you don't have to declare it it's already there and written bolded
bitTime >> 1 makes ONE bitshifting to the right. For binary numbers this is the same as dividing by 2
examples
now t contains a value actual systemvariable cnt + some time in the future
in waitcnt(t +=bitTime)
the "+= BitTime" sets the value of t more ahead into the future.
the += operator does the addition and as the "+" is in front of the "=" immediatly stores the RESULT into t
so t+=BitTime is s hort form of t := t + BitTime
this means waitcnt(t+= BitTime) waits until the systemcounter matches the value of t
best regards
Stefan
I read somewhere that the Parallax 433 MHz Transceivers had to use inverted signals. I'm not exactly sure what all
that means.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
Most logic operates at 0V/5V or, these days, 0V/3.3V. There has to be level shifting circuitry to interface to RS232 levels. Many interface circuits invert the signal just because of how they work. The system designer can add a logic inverter or change the way the UART works to invert the signal there and save a couple of parts. If you don't use RS232 and use straight logic level signalling to, say, a USB to logic level serial adapter, the signal may be inverted or not inverted depending on how the adapter is designed. It's useful to have a software serial driver that can handle (and be configured for) either case.
It's the complete program shown other than the called objects. I cannot get a good result no matter how I have
tried to call it. I tried calling tx, rx, str, strtobin, bin, hex and any others in the fullduplexserialplus list and all I get
is garbage out.
It's basically square one and I don't think it appears all that complicated, but I am having no luck.
Can someone please assist me with this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.
What do you want to send?
It's always more helpful for you to describe what you're trying to do in general descriptive terms. You can do it in your message or you can include the information as comments in your program or program fragment.
was receiving it's data was the variable called inverted. I just wanted to make a short quick program to mimic that part of the code so I could
find out what was actually happening in the inverted := baud < 0 statement. I know by their comments that it is supposed to be setting
the inverted flag, but I really don't know what that means or what it actually does. They later use the inverted variable in the waitpeq command.
I assume this is to invert the signal if needed. I just don't know how or why it does this. I also am not exactly sure how or which method to
call from the fullduplexserial object to show me this result.
I completely understand that what goes in comes out in programming. My problem isn't that I am expecting a certain result. My problem is that
I am simply guessing on the programming end and hoping to come across my result. Sort of like trying to find the square root of a number by
picking two arbitrary numbers, multiplying them, viewing the result, and narrowing them down until you get the answer. Believe me, I did not just
try this once and gave up. I have been at it all weekend. There's approximately 12 lines of programming in the simple serial file that accomplish
the data receive function and I only understand about half of them. So, I have spent many hours trying to decipher each piece of the program.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's not the size of the dog in the fight, but the size of the fight in the dog.