I plan on using the Arduino and Raspberry Pi in a project for an Energy Systems class in which my partner and I are examining a Parallel-Hybrid RC car. We are looking at the efficiency of our control schemes (when the engine/motors kick in) using the EPA's official driving cycles and a homebuilt dyno. These are two-column CSV's with the 1st column as time in seconds and the 2nd column as the speed in MPH.
My question is whether I set up a loop that changes the speed of the motor to the appropriate speed based on the time in each row. The question is more pertaining to how the time aspect of it is done, rather than the speed aspect. I also was wondering if there's a better way to pass these values to the Arduino then to define them as arrays and write them all out myself within the sketch (766 rows...), especially since we'll be moving to a variety of driving cycles. I was thinking of using the Pi to pull the values and talk to the Arduino via pySerial.
Thank you for your quick response. We are pretty constrained to what we have on hand so I'm tempted to use the RasPi if sending values over pySerial is the best option, or writing a couple copies of the same Arduino sketch, just with different hardcoded values. I'm using MatLab right now to extract the columns into csv arrays to paste into the arduino sketch, but am more concerned about handling the time properly.
My progress there has been defining "start", "end" and "elapsed" variables with millis, but I don't know how to use it properly within a for loop. Any help there would be appreciated.
ShinjitsuManifest:
I was thinking of using the Pi to pull the values and talk to the Arduino via pySerial.
I'd have thought the simplest solution would be to write a PC application that processed the file and sent commands to the Arduino to change the speed at the times indicated in the file. The PC application would be very simple, and all the Arduino would do is change the speed as it received the commands. Any old laptop would be sufficient for running the PC application, and you could keep a library of command sequences on the PC.
(If you wanted, you could use the same pipeline in reverse for data logging.)
PeterH, that sounds like the best approach to take, I'm just a little confused about how to do it. I wanted to use the Pi and Arduino together since writing Python on the Pi is so much better than on my Windows laptop and the Arduino is much better at handling the servos. Would the approach be to have the Pi keep track of time, send a value over each second, and when the Arduino receives that value it maps it to a servo speed?
You could set ISR (interrupt subroutine) firing at regular interval. Make your own or use a library, Metro, MsTimer2 or TimerOne. Inside you would need to compare current time with the data in first column of array (timing), if >= than output associated speed. You are saying, that time in seconds, what is the resolution?
Depends on it, you can organize data, rounding it to 100 msec base or 10 mseconds. Timing in the file should alway start from "0", current time of arduino you can adjust via offset tacking in setup().
I'll definitely look into the libraries you mentioned. This also brings something else to my attention. While the timing resolution is very low (it changes second to second, no milliseconds or anything) it is based on speed, so I probably would need it to keep looking a second or two ahead so it's already at the speed by the time the second occurs.
ShinjitsuManifest:
PeterH, that sounds like the best approach to take, I'm just a little confused about how to do it. I wanted to use the Pi and Arduino together since writing Python on the Pi is so much better than on my Windows laptop and the Arduino is much better at handling the servos. Would the approach be to have the Pi keep track of time, send a value over each second, and when the Arduino receives that value it maps it to a servo speed?
Thanks!
It's up to you to decide which PC development environment is most convenient for you and whether you want to do your development on a laptop, RPi, or whatever.
Rather than sending a command every second, I'd send a command when the speed needed to change. The code I was envisaging would just read a data file line by line, delaying by the amount specified and then sending a movement command to the Arduino. I'd expect this to take a couple of dozen lines of code at most. If you used C++ then it would be familiar from your Arduino programming experience. The stdio library makes it easy to open and read lines from a file and parsing a line of text is also straight forward.
Thanks for all the input and suggestions. For the time being, I'm trying to scale it down and want to tackle a more manageable question with just the Arduino. I have created an array containing the speed that the car has to be at for every second and in the loop I just delay 1000 milliseconds and try to change the PWM out based on this value so that it'll hold through the delay and update for the next second. However, with the servo library I cannot write speeds, but only angles, and so I'm wondering if you have any suggestions on a method to control motor speed from this array of values.
I'm not at all clear what your motor mechanism is. I'm guessing you're using servos modified for continuous rotation, in which case you can use angles to indicate speed: somewhere around 90 will be stop, 180 will be full speed in one direction, 0 will be full speed in the other.
wildbill:
I'm not at all clear what your motor mechanism is. I'm guessing you're using servos modified for continuous rotation, in which case you can use angles to indicate speed: somewhere around 90 will be stop, 180 will be full speed in one direction, 0 will be full speed in the other.
I had seen the servo library, but was confused. If I map speeds to angle, ie. map(mph, 0, 60, 90, 180), I am under the impression that it will not move at all in between seconds, or does the angle reset each time the command is sent? Also, since I am delaying for a second and then re-writing, will it get to the angle and then stop until it is written to again?
If it is an ordinary unmodifed servo, it will go to the angle you tell it to and stop. You can buy servos that have been modified (or do it yourself) so that they don't stop but just run forwards or back at variable speed. These are often used to act as wheel driving motors in small robots. The latter is what I guessed you had, but now it doesn't sound like it.
Your PWM method sounds plausible once you get your motor, but I'm at a loss as to what you can test with the servo - I suppose you could build a speedometer to display what speed the robot is supposed to be doing.