BTW, I was surprised that the ESC I was fooling around with was getting quite warm just from a few minutes of testing. May be those linear regulators knocking down 12V to 5?[/QUOTE]
Let me guess, you had your programming card plugged in?
With the card plugged in (whether or not the LEDs are on) the ESC plus card draw about 200mA. The ESC by itself only draws 20mA. I bet you're right about the linear regulators getting hot from dropping the 12V down to 5V.
I got the bug causing the delayed acknowledgement fixed. I also changed the code so instead of capturing high and low times it saves the highs and lows as ones and zeros (like the original code did (but with improved timing)). I think the main thing keeping the original code from capturing data from the ESC was the noise as the ESC was powered on.
Here's the latest output.
Almost ready to read parameters from ESC.After pressing any key to continue, you'll have 8 seconds to cycle the power of the ESC.
Press any key to continue.
Please cycle power on the ESC.
readEscDataReturn = Successfully received packet and sent acknowledgement.
Read from ESC result = %0111_0101_1101_0011_1110
End of Program
Here's the LA capture of the same data.
It's nice to see the ones and zeros of both the LA trace and the Propeller capture match.
The first two bits are always the same and are ignored. The input of the pin is sampled starting 2.5 bits worth of time from the first low pulse after a high pulse of at least 1.5 seconds.
I'll look back at the original code to see how to change the above ones and zeros in to parameter settings.
I think the Propeller can capture the pulses from the ESC even without a pull-up resistor as long as I don't connect the LA to the line.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
I noticed in the original code two sets of 8-bits were captured from the ESC data. In the above example, I captured 20-bits of data. Of these 20 bits only 14 hold useful data. The first bit captured above is always zero. The 2nd through 9th bit are useful data but then there are 4 bits which are always the same. The following 6-bit (after the four which don't change) are also useful data. The last 4-bits of the capture (by the Propeller) don't represent useful data. Now I understand how the original code could ignore the first few bits two different times as it captured a byte at a time.
IIRC, the original code captured the data in the opposite order my version of the program captures the data. Looking at traces of various parameter options I can see why the original code captured the bits in the order it did. The bit order makes more sense when it's reversed. Option values of one and two match the binary value with the bits reversed from the order shown above.
The reversed bits aren't a big deal, I can just use the "<>" (it's the >< (second time this week I did that)) operator to reverse the bits after they've been captured.
I'm pretty much convinced the original code should have worked fine if the problem from the noise of powering on the ESC hadn't been a problem.
I think I've the part which reads the data from the ESC working correctly (though I haven't tested it very thoroughly).
I'm back to the cosmetic aspect of the program.
I really like Russ' layout mentioned earlier in the thread but I'm not sure about how to make the "active" parameter known. I want to keep all the parameters and all the options visible in the terminal window as the selections are made.
Here's what I have so far.
Edit Parameters
Current Parameter Setting Default From ESC Options
0) Brake = Off Off Off Off, On
1) Battery Type = LiPo NiMH NiMH LiPo, NiMH
2) Cutoff Type = Soft-Cut Cut-Off Soft-Cut Soft-Cut, Cut-Off
3) Cutoff Voltage = High High Low Low, Middle, High
4) Start Mode = Very Soft Very Soft Normal Normal, Soft, Very Soft
5) Timing Mode = High High Low Low, Middle, High
6) "Music" = (not used) (not used) (not used) (not used)
7) Governor Mode = Off Off Off Off, On
Ready to Edit Parameter Default From ESC Options
0) Brake = Off Off Off Off, On,
Enter the parameter number you wish to edit.
Press "<" or ">" to select parameter setting.
The keys "a", "s", d"and "w" may also be used to select parameter and setting.
Press "h" for more information about using this program.
Press "t" to transmit these parameters to the ESC.
Press "L" to load default parameters into active array.
Press "r" to to use received parameters.
Press "x" to exit.
Brake = Off
When brake is on, the ESC will force the motor to slow down. When
is off the motor will coast.
I believe the "a", "s", d"and "w" keys are commonly used as arrow keys. I liked being able to navigate the options easily with one hand using the asdw keys (are they asdw of wasd?). The problem with using these keys is we lose the "s" and "d" keys which I had planned to use as "save" and "default".
For now, I'm using the "t" key instead of "s" and refer to "save" as "transmit". I'm also using "L" for "load" instead of default. I really don't like this. I was going to use the lower case "l" but it looks too much like a one.
I think the above display looks much better than my previous version (thanks to Russ) but I'm still not happy with it.
As I mentioned, I believe the portion of the program which receives data from the ESC is working correctly. I'll work on the part which sends data to the ESC. I don't think this will be hard since I can use the original code (with a few tweaks) by Frank and Roy to send the data.
I hope someone will try the attached code to read data from their ESCs. Then try changing parameters and let me know what should be changed.
I think using "exit" will end the program and "transmit" doesn't do anything (other than possibly end the program) but I think the other key press options should work.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
As soon as I posted the above I thought of a better way to display the data. I still don't really like it, but I think it's better than the last post's display.
Edit Parameters
Current Parameter Setting Default From ESC Options
0) Brake = Off Off Off Off, On
1) Battery Type = NiMH NiMH NiMH LiPo, NiMH
2) Cutoff Type = Cut-Off Cut-Off Soft-Cut Soft-Cut, Cut-Off
3) Cutoff Voltage = High High Low Low, Middle, High
4) Start Mode = Very Soft Very Soft Normal Normal, Soft, Very Soft
5) Timing Mode = High High Low Low, Middle, High
6) "Music" = (not used) (not used) (not used) (not used)
7) Governor Mode = Off Off Off Off, On
Brake = Off
When brake is on, the ESC will force the motor to slow down. When
is off the motor will coast.
Enter the parameter number you wish to edit.
Press "<" or ">" to select parameter setting.
The keys "a", "s", d"and "w" may also be used to select parameter and setting.
Press "h" for more information about using this program.
Press "t" to transmit these parameters to the ESC.
Press "L" to load default parameters into active array.
Press "r" to to use received parameters.
Press "x" to exit.
I moved the small "info" section to a higher position in the display. I had kept it low (in the display) since the varying info size would have made the display jump around. I "solved" the issue by making sure each info (formerly help) entry had the same number of lines as the rest of the entries.
IMO, it looks a better than my earlier attempts. I'm still not thrilled with it.
Back to adding code to send data.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
I used a Quickstart board with no pull-up on pin 26. The programming card did not match the Propeller output.
I also took LA traces
I'm not sure if will make a difference, but I tested with both the Prop / Prog Card attached and then with the Prop / Prog Card / Logic Analyzer attached. I thought about testing with just the Prop, but it was time to retire for the night.
The programming card did not match the Propeller output.
You were comparing the card with the settings to be set to the ESC. The settings read from the ESC are listed under "From ESC". The "From ESC" readings were blocked by your programming card insert.
The code I posted doesn't transmit any data to the ESC.
My latest version (not yet posted) transmits to the ESC but the acknowledgement is off. It acknowledges with 1441 instead of 1365 ($555). An earlier version acknowledged with 1025. I found these changing acknowledgment blips unexpected. I think the acknowledgment blips could be a useful diagnostic tool.
The ESC sends two bytes with the 14-bits of data. The programming card sends 12 bytes of data (including a byte count). It starts out sending the same two bytes the ESC would send but then it sends each parameter again with each parameter taking up one byte in the transmission. I'm starting to understand why Frank Zhao seemed a bit annoyed at me. There isn't anything wrong with his code. It's just my failure to understand the need of pull-up resistors that keep his code from working initially.
If you want to try the program with a pull-up resistor you can use one of the I2C lines. I've been using the I2C clock line on P28 (position 31 on the 40 pin header of the QuickStart board). Just make sure the ESC isn't powered on while programming the Prop. The ESC interferes with the EEPROM programming if it's left on (and connected).
I've found Roy's original program works great with a pull up on the line. If I use Roy's code, I can program the ESC just fine. My code still doesn't get it right yet. If I need to, I can revert to Frank's/Roy's transmission code. I have a few "short cuts" I want to use which appears to be causing a problem.
I thought I'd have the transmission side of this figured out by tonight but it looks like I won't have code to both receive and send data until tomorrow (I think).
The version which received strange acknowledgements from the ESC had a missing indentation after an if statement.
I had this:
repeat byteIndex from 0 to MAX_PARAMETER_INDEX
if byteIndex <> LIPO_CELLS
TPC_ser_write(byte[parameterPtr][byteIndex])
Where I intended to have:
repeat byteIndex from 0 to MAX_PARAMETER_INDEX
if byteIndex <> LIPO_CELLS
TPC_ser_write(byte[parameterPtr][byteIndex])
I've attached code which should both read from the ESC and write to the ESC.
I plan to start working on adding multiple signal lines tomorrow. My hope is all four (or more) ESCs can be programmed at once.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
The settings read from the ESC are listed under "From ESC". The "From ESC" readings were blocked by your programming card insert.
Oops - well it looks like I may have used older code (140731c.spin) since I didn't have a "From ESC" column. I'll give it another try and see what happens.
Oops - well it looks like I may have used older code (140731c.spin) since I didn't have a "From ESC" column. I'll give it another try and see what happens.
-Russ
I hope you try out the newer version. I haven't tested it very thoroughly so I'd be glad to have an extra set of eyes (and ESC) to test the code.
I found the terminal window wraps around after 128 characters. It's probably possible to add a few more columns to the current display:
Edit Parameters
1 2 3 4 5 6 7 8 9 0 1 2
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
90
Current Parameter Setting Default From ESC Options
0) Brake = Off Off Off Off, On
1) Battery Type = NiMH NiMH NiMH LiPo, NiMH
2) Cutoff Type = Cut-Off Cut-Off Soft-Cut Soft-Cut, Cut-Off
3) Cutoff Voltage = High High Low Low, Middle, High
4) Start Mode = Very Soft Very Soft Normal Normal, Soft, Very Soft
5) Timing Mode = High High Low Low, Middle, High
6) "Music" = (not used) (not used) (not used) (not used)
7) Governor Mode = Off Off Off Off, On
Brake = Off
When brake is on, the ESC will force the motor to slow down. When
is off the motor will coast.
Enter the parameter number you wish to edit.
Press "<" or ">" to select parameter setting.
The keys "a", "s", d"and "w" may also be used to select parameter and setting.
Press "h" for more information about using this program.
Press "t" to transmit these parameters to the ESC.
Press "L" to load default parameters into active array.
Press "r" to to use received parameters.
Press "x" to exit.
I added numbers showing the size of the display. (I hope this shows up correctly in the forum software.)
I might be possible to add three more "From ESC" columns but I think it would be better to have the "From ESC" readings listed above the settings being edited.
By moving the "From ESC" readings to above the editing area, there would be room for the six "From ESC" columns I want available.
The program currently uses two cogs. This leaves six extra cogs to read ESCs. I had (until I started to type this) thought I'd use five of the six cogs to capture a total of six ESC signals. Now I think it's a shame not to be able to use all eight cogs to capture up to eight signals (and program eight ESCs). I'd need to stop the cog running the serial driver and temporarily use the cog to capture the signal from the eighth ESC. It would certainly be possible to capture 8 signals with a PASM driver but there's something appealing about having all 8 cogs of the Propeller running the same code at once.
Before I get going on the 8-channel version of the code, I'll get this single channel version cleaned up a bit and make sure it can read back the data it had sent to make sure the data received back from the ESC matches what was sent.
It's been a while since I've done an ESC throttle calibration. I'm trying to remember if this is something the Propeller could do?
I'd think with the receiver connected to the Propeller, the throttle range could be captured by the Propeller and then this range could be passed on to all (4 to 8) ESCs connected to Propeller.
I seem to recall calibrating all the ESCs was a bit of a chore since each ESC had to be connected directly to the receiver and calibrated one at a time. I'll need to refresh my memory and see if this could be done all at once with the Propeller.
Nice progress! I have be dabbling with your code on and off, but I thought I'd give you latest code a try. Was able to program the standard Elev-8 ESC, (Yellow HW30A0), read back the parameters, and program it again. No pullups.
Two problems I had were:
1).Trying to reload your defaults, (L).Got this error when transmitting to ESC.
2). And the "<" and ">" do not work on my keyboard. (w,a,s,d work fine).
1).Trying to reload your defaults, (L).Got this error when transmitting to ESC.
That's interesting. I'll see if I can reproduce the error.
I hadn't seen that acknowledgement before. It looks like it was almost correct. I kind of wonder if not having a pull-up on the line made a difference?
2). And the "<" and ">" do not work on my keyboard. (w,a,s,d work fine).
Did you try to use the arrow keys? The "<" and ">" are the less than and greater than keys. The comma and period should also work.
I don't think there's a way to use the arrow keys as input with PST. It would be nice if the arrow keys did work with PST.
I was glad to hear the program worked as well as it did without pull-ups. I can capture the signal with the Propeller without pull-ups as long as I don't also attach the logic analyzer.
Yes, of course I was using the arrow keys, (senior moment). Less/Greater than work OK.
Are you using a resistor between the Signal and the Prop pin? I was not before. I put a 10K in series with signal line and a 20K pullup, (just to two that where within arms reach).
Seems to work now. Haven't tested it more than three times. I'll let you know.
I hope you don't mind me demonstrating this at the Boston Expo next weekend. I think the guys will get a kick out of this. Of course your name will be plastered on the screen.
Are you using a resistor between the Signal and the Prop pin? I was not before. I put a 10K in series with signal line and a 20K pullup, (just to two that where within arms reach).
You shouldn't need a series resistor. There is about 5V on the line (closer to 4V when connected to the Propeller) but it's a rather weak 5V/4V (limited in current). I haven't measure the current, but I'd be very surprised if it's not within the safe level.
I hope you don't mind me demonstrating this at the Boston Expo next weekend. I think the guys will get a kick out of this. Of course your name will be plastered on the screen.
Just make sure Frank Zhao and Roy Eltham are also mentioned. I think most of the credit goes to Frank. He's the one who figured out the protocol.
Edit: Has Roy always had a "L" in his last name? Sorry Roy, I'll have your name spelled correctly with the next version of the code posted.
1).Trying to reload your defaults, (L).Got this error when transmitting to ESC.
I get the error some of the times but not all the time. It's very strange.
This is the error message:
Received incorrect acknowledgment from ESC.
Expected acknowledgment from ESC to equal 1365, but instead it was 1237.
This is the latest version of the display:
Successfully received packet and sent acknowledgment.
The current parameter settings do not match the settings received from the ESC.
The new parameters will not be active until they have been transmitted.
Edit Parameters
Current Parameter Setting Default From ESC Options
0) Brake = Off Off Off Off, On
1) Battery Type = NiMH NiMH NiMH LiPo, NiMH
2)>Cutoff Type <= Cut-Off Cut-Off Cut-Off Soft-Cut, Cut-Off
3) Cutoff Voltage = High High High Low, Middle, High
4) Start Mode = Very Soft Very Soft Very Soft Normal, Soft, Very Soft
5) Timing Mode = High High Middle Low, Middle, High
6) "Music" = (not used) (not used) (not used) (not used)
7) Governor Mode = Off Off Off Off, On
Cutoff Type help goes here.
Enter the parameter number you wish to edit.
Press "<" or ">" to select parameter setting.
The keys "a", "s", d"and "w" may also be used to select parameter and setting.
Press "h" for more information about using this program.
Press "t" to transmit these parameters to the ESC.
Press "L" to load default parameters into active array.
Press "r" to to use received parameters.
Press "x" to exit.
Sending Data
Parameter being sent = 00_0010_0101_0110
Successfully received acknowledgment.
Received incorrect acknowledgment from ESC.
Expected acknowledgment from ESC to equal 1365, but instead it was 1237.
Press any key to continue.
And sure enough, the logic analyzer trace shows a strange acknowledgment from the ESC. Below are two traces with the same settings. The first set of traces were captured as the programming card communicated with the ESC. The lower set of traces is a capture of the Prop to ESC communication (same communication which produced the error message above).
I don't understand what the ESC doesn't like about the pulses. The duration of the pulses are pretty darn close to the duration from the programming card. (These traces always appear smaller than I expect. You might want to zoom in on them to get a better look.)
I just had an idea about what could be causing the problem.
The code to write to the ESC actively drives the signal line. This would cause the line to experience three different voltage states instead of just two. When the Propeller sets the I/O pin to an output while high, the voltage probably changes from 4V to 3.3V. This may be enough to confuse the ESC. I'm not sure if this is the problem, but I'm at a lose at what else could be causing the problem. The traces from the Propeller look identical to the traces from the programming card.
I've attached the LA files for the two traces. I couldn't find a timing difference between the two sets which I would think should cause trouble. This really makes me think the problem isn't the timing of the pulses but the shape of the pulses.
I'll change the code so it doesn't drive the line high and see if it helps.
I've also attached the latest version of the code. It's far from done but it's cleaner than the earlier versions I posted. If you're following along at home, this latest version is the one to try.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
Not actively driving the signal line appears to have fixed the communication problem.
I still have a problem with the data not being interpreted correctly. The "Timing Mode" parameter appears not to be read correctly. I likely have a bit out of place.
I still have a problem with the data not being interpreted correctly. The "Timing Mode" parameter appears not to be read correctly. I likely have a bit out of place.
I think the problem was a timing error. Spin was too slow to catch the data bit with all the overhead within the timing loop.
I think the fix is to not add the half bit delay when starting to read the data.
FIRST_BIT_TIME = (3 * BIT_TIME_WIDTH) '+ HALF_BIT
Commenting out "+ HALF_BIT" appears to fix the timing issue.
The other timing constants fix themselves since they use "FIRST_BIT_TIME" to calculate subsequent delays.
I'm updating the code so it doesn't automatically require one to cycle the ESC power every time data is transmitted but I haven't tested it yet. The fix I just mentioned should get the last version posted (140702g) working reasonably well.
Couple of quick tests still show about a 5% failure to program, (incorrect acknowledgement number). No biggie to just run it again.
One problem I did notice is the reporting of the "Timing Mode". It is reporting LOW when it is programmed for MIDDLE. The program does set the correct values, (as verified with the Programming Card), but the "From ESC") does not show up with the correct data.
It's been a while since I've done an ESC throttle calibration. I'm trying to remember if this is something the Propeller could do?
I'd think with the receiver connected to the Propeller, the throttle range could be captured by the Propeller and then this range could be passed on to all (4 to 8) ESCs connected to Propeller.
I seem to recall calibrating all the ESCs was a bit of a chore since each ESC had to be connected directly to the receiver and calibrated one at a time. I'll need to refresh my memory and see if this could be done all at once with the Propeller.
They can all be done at the same time and it is probably a good idea to do it that way to ensure everybody is set identically. To initiate throttle range, the throttle should be set full when energizing the ESC. It will recognize this and chirp out a different pattern (I can never remember exactly what they are). You then set the throttle to min within 2 sec's and you'll get a confirmation beep. Then all is set.
If you are running the HoverFly board then you are using a prop to set it. . I think the configuration used to fly (radio tx rx controller) should be used to synch and set throttle range.
I ran into a very odd situation when trying to implement Jason Dorie's code. He has a method to synch wherein he doesn't use the receiver input to set the endpoint of the the throttle range, he uses hard-coded values of 1 and 2ms, the nominal values. However, my radio does NOT output 1ms @ 0 throttle and 2ms @ full. So the ESC's get set to the theoretical values which does not match the radio. I was a little startled when my props started after enabling with the throttle @0!
While I was playing around the throttle settings, I noted that the ESC would "fault" if the throttle was not zero on power-up and it would go into "throttle ranging" if the throttle was full on power-up. Of course there is the question of what pulse width is 'not zero' and what is 'full'.
Here are the results I found on my ESC's
full throttle = greater than 1.5 ms pulse
error = greater than 1.2 ms and less than 1.5 ms
Note that all ESC's did not appear to behave identically. Some would "error" at a give throttle settings and others would not.
My radio (HiTech Aurora9) gives 1.12ms @ -100% and 1.88ms @ +100%
To get nominal values: 1 ms @ -130% and 2 ms @ +120%
It will recognize this and chirp out a different pattern (I can never remember exactly what they are). You then set the throttle to min within 2 sec's and you'll get a confirmation beep. Then all is set.
With full throttle up at power up, it will give two beeps. Throttle down will give three beeps. I just did mine again about 15 minutes ago.
In hopes of finding the timing issue, I added a debug pin to the code. I had the debug pin toggle right after the input pin was read to see where in the packet the bit was being read.
repeat FIRST_BITS_TO_CAPTURE
result <<= 1
timer += BIT_TIME_WIDTH
result += ina[escPin[index]]
[COLOR=#ff0000] !outa[DEBUG_PIN][/COLOR]
waitcnt(timer)
timer += SKIPPED_BITS_PAUSE ' skip four bits which don't change
waitcnt(timer)
repeat LAST_BITS_TO_CAPTURE
result <<= 1
timer += BIT_TIME_WIDTH
result += ina[escPin[index]]
[COLOR=#ff0000] !outa[DEBUG_PIN][/COLOR]
waitcnt(timer)
The top trace was with a three and a half bit pause before the signal pin was read for the first time and the second trace was with a three bit pause.
I think the time spent shifting the bit and adding to the timer created a half bit delay so by the time the pin was finally read, it would occasionally miss the correct time slot.
The lower trace of each pair is the debug pin toggling right after a bit has been read. You can see where in the transmission the first 8-bits are read and then there are four ignored bits followed by the remaining 6-bits.
I wonder what the "official" bits per second of the ESC communication protocol is. I initially used 2.5ms per bit but when I was having trouble with consistent readings, I switched to 2.616ms per bit since this is want my logic analyzer said the programming card used. I notice Frank's original code uses 2.437ms bits. My guess is the 2.5ms figure is probably the "official" figure and the other figures are the result of clock inaccuracies. I had thought the relatively short period where pulses are being measured (about 21-bits) I wouldn't need to worry about small timing differences between the various ESCs. I see now that 21-bits is plenty long enough for a small difference in timing to cause a big problem. To keep the error less than half a bit over 21-bits would require the timing to be withing 2.4% accuracy. The pulses times from my programming card and my ESC are different by over 3%.
I'm going to need to rewrite the capture section of the code.
There are a couple approaches I think could work.
1) Use the first few pulses to calibrate the timing. I think to do this accurately would require several waitpxx statements. This has the danger of causing the program to freeze.
2) Instead of just skipping the middle four bits, I could to use these to sync the timer back into alignment.
3) Use my earlier technique of capturing time intervals and sort through the intervals after they're captured to parse the ones and zeros.
4) Switch to PASM where there's all the time in the world to sync pulses and measure intervals.
I'm pretty sure something needs to be done to improve the timing. I'm open to suggestions on how to fix this problem but I don't think the program will be reliable until this issue is addressed.
I wonder what the "official" bits per second of the ESC communication protocol is. I initially used 2.5ms per bit but when I was having trouble with consistent readings, I switched to 2.616ms per bit since this is want my logic analyzer said the programming card used. I notice Frank's original code uses 2.437ms bits. My guess is the 2.5ms figure is probably the "official" figure and the other figures are the result of clock inaccuracies.
On Frank's site he has a comment from sputnik1892:
"Great work! I used the code for my Arduino MiniPro board (16 MHz) and applied it on 4 different Hobbywing-Pentium30A ESCs. All I had to change was:
- BaudRate Registers (UBRR0H / UBRR0L )
-pin registers for ESC and LED
-TPC_READ_BIT_TIME_WIDTH: this neede to be adapted for every ESC varying in my case from 2450 to 2750.
2750!? Wow.
2450 to 2750 is a big spread. Obviously we don't want to have to adjust some constant to make the code work with each new ESC. I'll get this figured out so it will automatically read from any compatible ESC.
I haven't had a chance to really give this thread a solid review lately but I can see forward progress is being made. I recognize there are at least two pieces of firmware in this mix that may have some unpredictable results (the ESC programming card and the ESC).
In the meantime we've got an intern (Daelin, a super cool high school senior who doubles as a Starbucks barista) configuring these one at a time. He's using a 12V power supply and ESC programming card. Appears the ESC must be powered externally, too.
Anyhow, I'm sure Duane will let me know when he's ready to turn this over to us. I really want to thank Duane for his excellent work here - this kind of contribution is so valuable to Parallax!
Anyhow, I'm sure Duane will let me know when he's ready to turn this over to us.
I just got the code to automatically detect bit length working. I'll have this integrated into the previous code to program a single ESC either later today or tomorrow.
I had planned to make the code work with up to 8 ESCs but it wouldn't be very hard to change the code so it could program 28 (possibly 30) ESC at once. If we reduced the number of ESC programmed at once to 24, there would be pins left over for input buttons and a LCD display.
I can't think of an easy way of reading 24 signals at once but since the Propeller listens for the acknowledgment, you don't really need to power cycle the ESC and read the data back. If the acknowledgement is good, the ESC should be properly programmed.
If you did want to read from 24 ESCs, you'd probably need to power them on in groups of 8.
In exchange for some Parallax goodies, I'd be willing to build a board to program 24 ESC at once independent of a PC. It would just need a 12V power supply.
I'm sure someone there could whip together a programming board with 24 servo connectors and 24 power clips. I could provide the software.
I hadn't been thinking about mass programming ESCs when writing the software. I envisioned the customer calibrating the ESCs themselves. I was planning on having the software able to program up to 8 ESC at once. The Spin version of the code can only listen to 8 signal lines at once.
I won't worry about trying to program more than 8 ESCs at once unless you request me to help make a mass programming program (and possibly hardware).
I'll make a separate post with an update about the program.
Comments
Let me guess, you had your programming card plugged in?
With the card plugged in (whether or not the LEDs are on) the ESC plus card draw about 200mA. The ESC by itself only draws 20mA. I bet you're right about the linear regulators getting hot from dropping the 12V down to 5V.
Here's the latest output.
Here's the LA capture of the same data.
It's nice to see the ones and zeros of both the LA trace and the Propeller capture match.
The first two bits are always the same and are ignored. The input of the pin is sampled starting 2.5 bits worth of time from the first low pulse after a high pulse of at least 1.5 seconds.
I'll look back at the original code to see how to change the above ones and zeros in to parameter settings.
I think the Propeller can capture the pulses from the ESC even without a pull-up resistor as long as I don't connect the LA to the line.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
IIRC, the original code captured the data in the opposite order my version of the program captures the data. Looking at traces of various parameter options I can see why the original code captured the bits in the order it did. The bit order makes more sense when it's reversed. Option values of one and two match the binary value with the bits reversed from the order shown above.
The reversed bits aren't a big deal, I can just use the "<>" (it's the >< (second time this week I did that)) operator to reverse the bits after they've been captured.
I'm pretty much convinced the original code should have worked fine if the problem from the noise of powering on the ESC hadn't been a problem.
I'm back to the cosmetic aspect of the program.
I really like Russ' layout mentioned earlier in the thread but I'm not sure about how to make the "active" parameter known. I want to keep all the parameters and all the options visible in the terminal window as the selections are made.
Here's what I have so far.
I believe the "a", "s", d"and "w" keys are commonly used as arrow keys. I liked being able to navigate the options easily with one hand using the asdw keys (are they asdw of wasd?). The problem with using these keys is we lose the "s" and "d" keys which I had planned to use as "save" and "default".
For now, I'm using the "t" key instead of "s" and refer to "save" as "transmit". I'm also using "L" for "load" instead of default. I really don't like this. I was going to use the lower case "l" but it looks too much like a one.
I think the above display looks much better than my previous version (thanks to Russ) but I'm still not happy with it.
As I mentioned, I believe the portion of the program which receives data from the ESC is working correctly. I'll work on the part which sends data to the ESC. I don't think this will be hard since I can use the original code (with a few tweaks) by Frank and Roy to send the data.
I hope someone will try the attached code to read data from their ESCs. Then try changing parameters and let me know what should be changed.
I think using "exit" will end the program and "transmit" doesn't do anything (other than possibly end the program) but I think the other key press options should work.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
I moved the small "info" section to a higher position in the display. I had kept it low (in the display) since the varying info size would have made the display jump around. I "solved" the issue by making sure each info (formerly help) entry had the same number of lines as the rest of the entries.
IMO, it looks a better than my earlier attempts. I'm still not thrilled with it.
Back to adding code to send data.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
Tonight I was able to take your .spin for a 'spin'
I'm using an ESC marked HW30A, purchased from Parallax. They refer to it as a GemFan. http://www.parallax.com/product/750-90000
Here are some pics:
I used a Quickstart board with no pull-up on pin 26. The programming card did not match the Propeller output.
I also took LA traces
I'm not sure if will make a difference, but I tested with both the Prop / Prog Card attached and then with the Prop / Prog Card / Logic Analyzer attached. I thought about testing with just the Prop, but it was time to retire for the night.
-Russ
You were comparing the card with the settings to be set to the ESC. The settings read from the ESC are listed under "From ESC". The "From ESC" readings were blocked by your programming card insert.
The code I posted doesn't transmit any data to the ESC.
My latest version (not yet posted) transmits to the ESC but the acknowledgement is off. It acknowledges with 1441 instead of 1365 ($555). An earlier version acknowledged with 1025. I found these changing acknowledgment blips unexpected. I think the acknowledgment blips could be a useful diagnostic tool.
The ESC sends two bytes with the 14-bits of data. The programming card sends 12 bytes of data (including a byte count). It starts out sending the same two bytes the ESC would send but then it sends each parameter again with each parameter taking up one byte in the transmission. I'm starting to understand why Frank Zhao seemed a bit annoyed at me. There isn't anything wrong with his code. It's just my failure to understand the need of pull-up resistors that keep his code from working initially.
If you want to try the program with a pull-up resistor you can use one of the I2C lines. I've been using the I2C clock line on P28 (position 31 on the 40 pin header of the QuickStart board). Just make sure the ESC isn't powered on while programming the Prop. The ESC interferes with the EEPROM programming if it's left on (and connected).
I've found Roy's original program works great with a pull up on the line. If I use Roy's code, I can program the ESC just fine. My code still doesn't get it right yet. If I need to, I can revert to Frank's/Roy's transmission code. I have a few "short cuts" I want to use which appears to be causing a problem.
I thought I'd have the transmission side of this figured out by tonight but it looks like I won't have code to both receive and send data until tomorrow (I think).
The version which received strange acknowledgements from the ESC had a missing indentation after an if statement.
I had this:
Where I intended to have:
I've attached code which should both read from the ESC and write to the ESC.
I plan to start working on adding multiple signal lines tomorrow. My hope is all four (or more) ESCs can be programmed at once.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
Oops - well it looks like I may have used older code (140731c.spin) since I didn't have a "From ESC" column. I'll give it another try and see what happens.
-Russ
I hope you try out the newer version. I haven't tested it very thoroughly so I'd be glad to have an extra set of eyes (and ESC) to test the code.
I found the terminal window wraps around after 128 characters. It's probably possible to add a few more columns to the current display:
I added numbers showing the size of the display. (I hope this shows up correctly in the forum software.)
I might be possible to add three more "From ESC" columns but I think it would be better to have the "From ESC" readings listed above the settings being edited.
By moving the "From ESC" readings to above the editing area, there would be room for the six "From ESC" columns I want available.
The program currently uses two cogs. This leaves six extra cogs to read ESCs. I had (until I started to type this) thought I'd use five of the six cogs to capture a total of six ESC signals. Now I think it's a shame not to be able to use all eight cogs to capture up to eight signals (and program eight ESCs). I'd need to stop the cog running the serial driver and temporarily use the cog to capture the signal from the eighth ESC. It would certainly be possible to capture 8 signals with a PASM driver but there's something appealing about having all 8 cogs of the Propeller running the same code at once.
Before I get going on the 8-channel version of the code, I'll get this single channel version cleaned up a bit and make sure it can read back the data it had sent to make sure the data received back from the ESC matches what was sent.
I'd think with the receiver connected to the Propeller, the throttle range could be captured by the Propeller and then this range could be passed on to all (4 to 8) ESCs connected to Propeller.
I seem to recall calibrating all the ESCs was a bit of a chore since each ESC had to be connected directly to the receiver and calibrated one at a time. I'll need to refresh my memory and see if this could be done all at once with the Propeller.
Nice progress! I have be dabbling with your code on and off, but I thought I'd give you latest code a try. Was able to program the standard Elev-8 ESC, (Yellow HW30A0), read back the parameters, and program it again. No pullups.
Two problems I had were:
1).Trying to reload your defaults, (L).Got this error when transmitting to ESC.
2). And the "<" and ">" do not work on my keyboard. (w,a,s,d work fine).
Jim
That's interesting. I'll see if I can reproduce the error.
I hadn't seen that acknowledgement before. It looks like it was almost correct. I kind of wonder if not having a pull-up on the line made a difference?
Did you try to use the arrow keys? The "<" and ">" are the less than and greater than keys. The comma and period should also work.
I don't think there's a way to use the arrow keys as input with PST. It would be nice if the arrow keys did work with PST.
I was glad to hear the program worked as well as it did without pull-ups. I can capture the signal with the Propeller without pull-ups as long as I don't also attach the logic analyzer.
Thank you very much for the feedback.
Are you using a resistor between the Signal and the Prop pin? I was not before. I put a 10K in series with signal line and a 20K pullup, (just to two that where within arms reach).
Seems to work now. Haven't tested it more than three times. I'll let you know.
I hope you don't mind me demonstrating this at the Boston Expo next weekend. I think the guys will get a kick out of this. Of course your name will be plastered on the screen.
You shouldn't need a series resistor. There is about 5V on the line (closer to 4V when connected to the Propeller) but it's a rather weak 5V/4V (limited in current). I haven't measure the current, but I'd be very surprised if it's not within the safe level.
Just make sure Frank Zhao and Roy Eltham are also mentioned. I think most of the credit goes to Frank. He's the one who figured out the protocol.
Edit: Has Roy always had a "L" in his last name? Sorry Roy, I'll have your name spelled correctly with the next version of the code posted.
Franks contribution:
http://eleccelerator.com/turnigy-esc-programming-card-reverse-engineered/
Roy's contribution:
Post #5
I get the error some of the times but not all the time. It's very strange.
This is the error message:
This is the latest version of the display:
And sure enough, the logic analyzer trace shows a strange acknowledgment from the ESC. Below are two traces with the same settings. The first set of traces were captured as the programming card communicated with the ESC. The lower set of traces is a capture of the Prop to ESC communication (same communication which produced the error message above).
I don't understand what the ESC doesn't like about the pulses. The duration of the pulses are pretty darn close to the duration from the programming card. (These traces always appear smaller than I expect. You might want to zoom in on them to get a better look.)
I just had an idea about what could be causing the problem.
The code to write to the ESC actively drives the signal line. This would cause the line to experience three different voltage states instead of just two. When the Propeller sets the I/O pin to an output while high, the voltage probably changes from 4V to 3.3V. This may be enough to confuse the ESC. I'm not sure if this is the problem, but I'm at a lose at what else could be causing the problem. The traces from the Propeller look identical to the traces from the programming card.
I've attached the LA files for the two traces. I couldn't find a timing difference between the two sets which I would think should cause trouble. This really makes me think the problem isn't the timing of the pulses but the shape of the pulses.
I'll change the code so it doesn't drive the line high and see if it helps.
I've also attached the latest version of the code. It's far from done but it's cleaner than the earlier versions I posted. If you're following along at home, this latest version is the one to try.
Edit(3/11/15): Warning, the code attached is an old version. There are likely better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't code similar to what is attached here on my on GitHub, send me a message and I'll make and check for any improved versions of the code.
I still have a problem with the data not being interpreted correctly. The "Timing Mode" parameter appears not to be read correctly. I likely have a bit out of place.
I think the problem was a timing error. Spin was too slow to catch the data bit with all the overhead within the timing loop.
I think the fix is to not add the half bit delay when starting to read the data.
Commenting out "+ HALF_BIT" appears to fix the timing issue.
The other timing constants fix themselves since they use "FIRST_BIT_TIME" to calculate subsequent delays.
I'm updating the code so it doesn't automatically require one to cycle the ESC power every time data is transmitted but I haven't tested it yet. The fix I just mentioned should get the last version posted (140702g) working reasonably well.
Will let you know my findings.
One problem I did notice is the reporting of the "Timing Mode". It is reporting LOW when it is programmed for MIDDLE. The program does set the correct values, (as verified with the Programming Card), but the "From ESC") does not show up with the correct data.
Did you apply the fix from post #80?
I was having the same problem but I thought removing the extra half bit delay fixed things (though I didn't test it thoroughly).
They can all be done at the same time and it is probably a good idea to do it that way to ensure everybody is set identically. To initiate throttle range, the throttle should be set full when energizing the ESC. It will recognize this and chirp out a different pattern (I can never remember exactly what they are). You then set the throttle to min within 2 sec's and you'll get a confirmation beep. Then all is set.
If you are running the HoverFly board then you are using a prop to set it. . I think the configuration used to fly (radio tx rx controller) should be used to synch and set throttle range.
I ran into a very odd situation when trying to implement Jason Dorie's code. He has a method to synch wherein he doesn't use the receiver input to set the endpoint of the the throttle range, he uses hard-coded values of 1 and 2ms, the nominal values. However, my radio does NOT output 1ms @ 0 throttle and 2ms @ full. So the ESC's get set to the theoretical values which does not match the radio. I was a little startled when my props started after enabling with the throttle @0!
While I was playing around the throttle settings, I noted that the ESC would "fault" if the throttle was not zero on power-up and it would go into "throttle ranging" if the throttle was full on power-up. Of course there is the question of what pulse width is 'not zero' and what is 'full'.
Here are the results I found on my ESC's
full throttle = greater than 1.5 ms pulse
error = greater than 1.2 ms and less than 1.5 ms
Note that all ESC's did not appear to behave identically. Some would "error" at a give throttle settings and others would not.
My radio (HiTech Aurora9) gives 1.12ms @ -100% and 1.88ms @ +100%
To get nominal values: 1 ms @ -130% and 2 ms @ +120%
This was a real surprise for me.
-Russ
With full throttle up at power up, it will give two beeps. Throttle down will give three beeps. I just did mine again about 15 minutes ago.
The top trace was with a three and a half bit pause before the signal pin was read for the first time and the second trace was with a three bit pause.
I think the time spent shifting the bit and adding to the timer created a half bit delay so by the time the pin was finally read, it would occasionally miss the correct time slot.
The lower trace of each pair is the debug pin toggling right after a bit has been read. You can see where in the transmission the first 8-bits are read and then there are four ignored bits followed by the remaining 6-bits.
I wonder what the "official" bits per second of the ESC communication protocol is. I initially used 2.5ms per bit but when I was having trouble with consistent readings, I switched to 2.616ms per bit since this is want my logic analyzer said the programming card used. I notice Frank's original code uses 2.437ms bits. My guess is the 2.5ms figure is probably the "official" figure and the other figures are the result of clock inaccuracies. I had thought the relatively short period where pulses are being measured (about 21-bits) I wouldn't need to worry about small timing differences between the various ESCs. I see now that 21-bits is plenty long enough for a small difference in timing to cause a big problem. To keep the error less than half a bit over 21-bits would require the timing to be withing 2.4% accuracy. The pulses times from my programming card and my ESC are different by over 3%.
I'm going to need to rewrite the capture section of the code.
There are a couple approaches I think could work.
1) Use the first few pulses to calibrate the timing. I think to do this accurately would require several waitpxx statements. This has the danger of causing the program to freeze.
2) Instead of just skipping the middle four bits, I could to use these to sync the timer back into alignment.
3) Use my earlier technique of capturing time intervals and sort through the intervals after they're captured to parse the ones and zeros.
4) Switch to PASM where there's all the time in the world to sync pulses and measure intervals.
I'm pretty sure something needs to be done to improve the timing. I'm open to suggestions on how to fix this problem but I don't think the program will be reliable until this issue is addressed.
On Frank's site he has a comment from sputnik1892:
"Great work! I used the code for my Arduino MiniPro board (16 MHz) and applied it on 4 different Hobbywing-Pentium30A ESCs. All I had to change was:
- BaudRate Registers (UBRR0H / UBRR0L )
-pin registers for ESC and LED
-TPC_READ_BIT_TIME_WIDTH: this neede to be adapted for every ESC varying in my case from 2450 to 2750.
Not very encouraging for fixed timing....
-Russ
I hadn't seen that. Thanks.
2750!? Wow.
2450 to 2750 is a big spread. Obviously we don't want to have to adjust some constant to make the code work with each new ESC. I'll get this figured out so it will automatically read from any compatible ESC.
And I thought I was almost done.
I haven't had a chance to really give this thread a solid review lately but I can see forward progress is being made. I recognize there are at least two pieces of firmware in this mix that may have some unpredictable results (the ESC programming card and the ESC).
In the meantime we've got an intern (Daelin, a super cool high school senior who doubles as a Starbucks barista) configuring these one at a time. He's using a 12V power supply and ESC programming card. Appears the ESC must be powered externally, too.
Anyhow, I'm sure Duane will let me know when he's ready to turn this over to us. I really want to thank Duane for his excellent work here - this kind of contribution is so valuable to Parallax!
Ken Gracey
I just got the code to automatically detect bit length working. I'll have this integrated into the previous code to program a single ESC either later today or tomorrow.
I had planned to make the code work with up to 8 ESCs but it wouldn't be very hard to change the code so it could program 28 (possibly 30) ESC at once. If we reduced the number of ESC programmed at once to 24, there would be pins left over for input buttons and a LCD display.
I can't think of an easy way of reading 24 signals at once but since the Propeller listens for the acknowledgment, you don't really need to power cycle the ESC and read the data back. If the acknowledgement is good, the ESC should be properly programmed.
If you did want to read from 24 ESCs, you'd probably need to power them on in groups of 8.
In exchange for some Parallax goodies, I'd be willing to build a board to program 24 ESC at once independent of a PC. It would just need a 12V power supply.
I'm sure someone there could whip together a programming board with 24 servo connectors and 24 power clips. I could provide the software.
I hadn't been thinking about mass programming ESCs when writing the software. I envisioned the customer calibrating the ESCs themselves. I was planning on having the software able to program up to 8 ESC at once. The Spin version of the code can only listen to 8 signal lines at once.
I won't worry about trying to program more than 8 ESCs at once unless you request me to help make a mass programming program (and possibly hardware).
I'll make a separate post with an update about the program.