For those of you that use or have used other microchips ...
turbosupra
Posts: 1,088
What chip has good/existing support for Windows applications and duplex usb (serial) communication through a Windows application.
To be a bit more specific, I have been tinkering in my free time with trying to read from and write to the propeller from a GUI that I'll write in c sharp. I recently had a hard drive physical failure on the machine that had all of my spin code and it may be more advantageous to just start new with a chip that has more readily available classes for data communication via a Windows GUI and serial/usb.
I don't want to, nor do I have time to reinvent the wheel, so if I can, I would like to use what is already out there if possible. I've made a few posts about this before and this does not seem to be something anyone else (aside from Hanno) is doing. Even the parallax engineer that returned my support request, did not have a very clear solution as to how to do this. The closer in general design to the prop, the better (via voltage values, number of pins, etc) .
To be a bit more specific, I have been tinkering in my free time with trying to read from and write to the propeller from a GUI that I'll write in c sharp. I recently had a hard drive physical failure on the machine that had all of my spin code and it may be more advantageous to just start new with a chip that has more readily available classes for data communication via a Windows GUI and serial/usb.
I don't want to, nor do I have time to reinvent the wheel, so if I can, I would like to use what is already out there if possible. I've made a few posts about this before and this does not seem to be something anyone else (aside from Hanno) is doing. Even the parallax engineer that returned my support request, did not have a very clear solution as to how to do this. The closer in general design to the prop, the better (via voltage values, number of pins, etc) .
Comments
By the way an AppNote has been provided by Parallax discussing Propeller to PC communication with code examples for Propeller and PC. However if your message is to find another product the message is not suitable in the Propeller forum.
So the question is, what is it that you actually want to acheive with the MCU? Can the Prop do it? If not why not and what other device can?
As you have not given any clue about the nature of your project it's impossible to advise so please do elaborate.
http://forums.parallax.com/showthread.php?126486-What-could-we-stuff-into-a-100kB-quot-Prop-Welcome-Mat-quot-drive-image&p=1032241#post1032241
http://forums.parallax.com/showthread.php?133979-Project-In-Progress-New-Serial-Terminal-Taking-Suggestions
Duane
My project controls functions in an automotive application. I want to be able to receive data, display it in real time and log it ... then write data, update values in real time and then start the process again of looking at the real time data that is received.
I know the prop can do it, because Hanno has written code to do this, but I am not anywhere near the programmer that Hanno is. I've used his logger and it is great, but if this project comes to fruition I will need to write my own code to receive data, as well as have a way to update spin code variables on the propeller itself. I will look for your thread, if I can get a baseline to where I can read and write to the prop with a working example, I can build from there ... I am not at the point where I could write the code from scratch and have it work.
@Chris - if a prop solution is readily available, I would choose that over starting from scratch and if it is not I wanted some opinions on what others with more experience than I had on my situation
@Duane - I will check those out, thank you
I have an AVR chip, and there are bazzillions of libraries and examples for these parts. Each part has a different collection of physical peripherals, etc. so each part has its own set of baggage that must be handled.
In my case the part ATmega103 was discontinued, and the weird hardware uart changed on the replacement ATmega128, and the software no longer worked. Getting the new part to work would be a matter of figuring out the assembler code for the interrupts, and straightening out the libraries. This should be no problem for someone who knows or wants to learn and become and expert on AVR assembler, but I do not; I want to concentrate on the application. It was much easier to switch to the prop and remove the entire class of variables related to the micro controller family. For what its worth, its much easier for me to experiment on a "larger" prop and leave converting to a "smaller" more specific part (for production) to somebody else. But, I tend to do things the easy way, being a bit lazy.
It sounds like you are asking for a high level protocol binding between a Prop and PC. As far as I know a standard does not exist because most programmers will complain that the binding is to restrictive. Therefore, we (programmers) establish a custom protocol or language that both the Prop and PC are programmed to understand.
A protocol might look like the following. Read Pin 1...
Simple C# open source serial port listener.
http://www.agaverobotics.com/SerialPortDemo.zip
However it does not help with the problem of how the data traveling over the link is generated and interpretted. The "protocol" that is. As far as the application code at the mcu and PC ends is concerned it still just a serial link shifting bytes up and down.
In addition with a single core chip like that you are in the world of interrupts in order get what you want done. Rather than the elegant simplicity the Props multicore architecture offers.
So, for production runs of cheap gadgets go with something like a LPC. For one offs go the easy way with the Prop, a serial USB adapter and something like FullDuplexSerial.
But then, even with the Prop you can ditch the adapter and do USB directly using mparks usb object.
2) You call either the rxcheck method, retime method, or the rx method depending on what features you want. rx always waits for a character. rxcheck always returns a value, either the received character or a -1 indicating that the input buffer was empty. rxtime is like rxcheck, but it uses a (supplied) timeout and waits up to that time for a character to be received, then returns either a -1 or the value of the character.
For more complex data (other than a single character at a time), you'd used an object like FullDuplexSerialPlus which adds some routines to handle formatted data like decimal values.
If I want to read a uni-directional input from an anemometer, to use an example, I would call the "rx" method in my main method to receive and write my 8 bits of data into the (returned) variable rxByte. Right?
I imagine that I now have a table of 8-bit values that correspond to different wind velocities (again using the anemometer example). What's the best way to compare the rxByte array and find the corresponding windspeed? Do you just run your rxByte through a loop where it is compared against each value in the wind velocities array? Is this the best way to get/store/output your final value (again, in this case it would be the actual windspeed that corresponds to the byte of data received from the anemometer.
Note: All methods in spin have a return value which is value of the call to the method. That makes all method calls function calls. When you're just using the method as a subroutine, the return value is ignored. By default, the return value is zero, so this all works out. For convenience and clarity, you can rename the return value from "result" to anything you want like "rxByte". Renaming it doesn't change it's behavior.
The easiest way to do the kind of conversion you want is to make a lookup table. In your case, all possible values of the 8-bit byte have wind velocity values, so you want a 256 entry table of wind velocities. Each time you get an 8-bit anemometer value, you use that as an index into the table to get your wind velocity. For small tables, you can also use the LOOKUP or LOOKUPZ statements which do the same kind of thing. They just embed the table in the statement itself.
Preinitialized tables are done in an odd way in Spin ... actually in the Propeller's assembly language like this:
Jeremy
If I were to use the FullDuplexSerial object and let's assume that the transmission of the data from the computer to the propeller is done correctly, how will the spin code delineate a variable name and variable value from the binary it is being sent. I believe the prop uses 8N1, so it will send 8 bits and a stop bit. Can someone briefly map this out for me please.
Lets say the data I want to send is:
(variable)
011101100111011001110100011011000101001001110000011011010101011001100001011011000111010101100101010101010111000001100100011000010111010001100101
(value)
00110110001100000011000000110000
Do I need something that sends serially a variable name, then a delimiter and then a value? So variable/value? And then a routine that does (sort of) a string split or string contains when it is able to recognize the variable portion, so spin can then extract the value portion?
If I'm completely off, and I want to send the following which is variable/value, with the "/" being the delimiter , how would I program spin code to receive this data to update an existing variable?
0111011001110110011101000110110001010010011100000110110101010110011000010110110001110101011001010101010101110000011001000110000101110100011001010010111100110110001100000011000000110000
You will have to program all the bits and pieces to figure out what variable to set and to do the actual work. If I were doing this, I would probably pick two different delimiters, maybe "=" and carriage return. Everything up to the "=" would be the value label and everything from the "=" to the return would be the value. I would use the Extended Full Duplex Serial object, modify it to use a delimiter character supplied by me when I call the routines and call the string input routine to get the value label text, then call the number input routine to get the corresponding value, look up the string in a table of such names, and update the variable value corresponding to the name, probably using some kind of CASE statement.
You might look at the source code for FemtoBasic (in the OBEX). There's a nice routine near the end of FemtoBasic.spin called getAnyNumber that takes the characters from a byte array and returns the value of the number found there and stops with the pointer to the characters (tp) pointing to the first "illegal" character in the value. It allows for decimal, hexadecimal, and binary values as well as single quoted characters (as a numeric value).
If have a few more questions (I'm trying to think this through and ask intelligent questions). Do have to provide EFDS.RxStr a byte array? Will FullDuplexSerial detect all of the binary values and assemble a byte array after compiling each set of 8 bits into a byte?
So I could write something close to the following?
Computer sends (the first bold is the "=" sign and the second bold is the "(13)") ASCII is " vvtlRpmValueUpdate=6000(13) "
011101100111011001110100011011000101001001110000011011010101011001100001011011000111010101100101010101010111000001100100011000010111010001100101001111010011011000110000001100000011000000101000001100010011001100101001
Prop receives and runs through
It will terminate the byte addition in the RxStr function after the final character in this string (and set the preceding last byte to 0)
011101100111011001110100011011000101001001110000011011010101011001100001011011000111010101100101010101010111000001100100011000010111010001100101
because following that is 00111101 representing the "=" sign. Then it copies the string to stringptr, which the prop reads as it is a predefined variable somewhere else in the program (this parts is a little confusing)? Then after that I run the rxDec routine?
Is this a start in the right direction? (I don't have access to a prop to test right now) I'm close to feeling like I have a a grasp on the whole picture and I see how the routines assemble byte arrays, but I'm still not clear on how I'm to delineate between the variable and the value.
The comments for Rxstr state
vvtlRpmValueUpdate is 18 characters so the initial read would contain vvtlRpmValueUpd.
This line of code...
Variable contains a pointer to the string. That is, the value of "variable" is the starting memory address of a string. Therefore, the conditional statement below will (most likely) never be true.
Use the strcomp() method to check if two strings are equal, page 203 in the Propeller manual. Also take a look at the BYTE data type on page 51. This section explains how a string is an array of bytes with excellent examples.
My suggestion is to put Extended_FDSerial on the self for a bit. Load the Parallax Serial Terminal Demo that comes with the Spin Tool. You can find it by selecting "Propeller Library - Demos" from the recent files drop down list in the left pane. The Parallax Serial Terminal Demo takes input from the Parallax Serial Terminal, manipulates the input, and displayed the results. The demo will provide a good basis for understanding serial data.
In the code you've posted, you're confusing strings and the address of strings. Spin doesn't really have strings although you can write string constants. What gets passed around is the address of the first byte of a sequence of bytes terminated by a byte containing zero. This is the same convention that's used in C and some other languages. .RxStr returns such an address.
Mike G has a good point. You should first spend some time with some of the demo programs that deal with serial I/O. Forget about all the 0 and 1 bits and focus on the bytes that are transferred back and forth. The whole purpose of FullDuplexSerial and its cousins is to hide the details of how the bytes are transferred so you don't have to worry about that. Do look at Extended_FDSerial and experiment with it. Either add some debugging statements to show what's happening inside the Extended_FDSerial routines or invest in a debugging tool like ViewPort and use that to watch what's going on until you understand it.
I will work with the demos so that I can see cause and effect. I own a viewport license, although my laptop had a head failure on the hard drive, so I will have to reinstall it and try and use it more effectively based on the explanations you and Mike G have given me. Thank you.
I'm not sure why the below code is not working. It appears I'm going to have to become familiar with string manipulation in spin. Maybe someone can tell me what I'm overlooking here? Thanks for reading!
Parallax Serial Terminal.spinStrings.spin
It's helpful if you tell us what you expect to happen and what actually happens. Anyway, I fixed the first part of your code. Inline strings need to be inside of the string() method. Use the DEC method of PST to display an integer.
I can't make heads or tails of the second part.
Thank you for the help, sorry I forgot the explanation. What I'm trying to do is to have the prop parse 1 string into 2 strings. So let's say the string was Mike=29. I'd want it to identify the delimiter (equals sign) and then I can hopefully use the StrParse method or something like it to split the string into a variable name ("Mike") and a variable value ("29") and then copy them to permanent memory addresses and clear the temporary cache of rxString (and possibly rxString2 if I need to use it)
The part underneath was me trying to tweak a function to string split, the code is inside of the strings.spin attachment from the previous post and it probably won't be necessary once I understand how to use this code.
It looks like some of the string functions I use in c#, but I'm not able to make the methods work?
Let me see if I can make some progress now
How can I copy my string manipulations to a new location in memory?
BYTEMOVE(@tempString,@rxString,16)
Remember that the amount to be copied has to include the zero byte that marks the end of the string.
I am so close now, but there is something I missing which is why I'm getting the output results below, care to straighten me out on this?
I've attached my code and the dependent objects in this post, what I expect is to separate the incoming serial string into 2 independent values, which are printed as 2 separate variables in the last terminal output which is " 10.) " . It should have read as " The individual Tom is 100 years old. "
Parallax Serial Terminal.spin Strings.spin testcode2.spin
You could call this like so
I know beggars can't be choosers, but do you have any idea why my function was returning incorrect data? I can't think of a reason why if I call a string display once and then a second time a few lines of code later, without altering it, that it would display something completely different then the first time. Even if my function cannot be used, I'd like to know for future spin coding why that is happening?
To me it looks as if the bytemove is not creating an independent variable for some reason?
I was originally rechecking the value of step 4, in step 8. I took step 8 and I tested it after step 5 and step 6 (no need to run after step 4 or 7) and somehow at step 6, one variables actions are still manipulating the other variables actions and it changes. Do you know why this is happening?