Jump to content

Recommended Posts

Following on from this thread, I think I'm now ready to start on the long and crazy path down building my own custom MFU using an Arduino Mega and some additional bits and bobs.  Big shouts must go to @Ray_ve and @Nobbi1977 for their quick advice and useful info, without which I might have lost faith in the project and let it stall.

So, what have I got planned, and will it all get done?  Well, who knows for sure?  This will be a fairly open-ended project and could keep me busy for a few weeks, a few months, or even a few years.  I'm not 100% sure if and when I'll hit the limits of the Arduino Mega.  I'm hoping I won't overflow the number of available inputs and outputs (the Mega has more than the Uno but I haven't done a complete count of my function list against the available ports yet), and I'm hoping I'll be able to buy a budget multi-channel handset that has the right number of the right type of switches (I have planned on using a lot of 3-way switches but my 6-channel Turnigy handset only has one 3-way switch, the rest are 2-way or dials).  I don't know how easy it might be to swap out 2-way switches for 3-way switches on a budget radio - I'm guessing 'not easy'.  So there may be quite a lot of re-thinking my inputs to get the functionality I want.

Anyhoo, what does the project involve, and what am I hoping to achieve?

Phase 1:

Full lights - headlights, tail lights, brake lights, turn signals, fog lights, reversing lights.

Driving modes - Off, Drive, Park.  In Off mode, lighting will continue to work but no motor or steering input or other functionality will work.  The throttle will be at the neutral position and ESC will have a drag brake, so the truck will not move.  In Drive mode, the motor will drive the wheels and steering input will operate the steering servo.  Park Mode will be much like Off mode and will not be used until a later phase.

Gear select: I don't intend to use the Tamiya 3-speed gearbox.  Instead I'll have a fixed ratio.  Hopefully I can find a transmission that will do this so I can save some space under the cab, otherwise I'll fix the Tamiya transmission into 1st gear.  Gear select will be a toggle switch so select Fwd/Rev (or Fwd/Neutral/Rev depending on handset functionality).  In Neutral mode, the truck will not move when the throttle is applied.  In Fwd, the motor will turn in a forward direction when up stick is applied.  In Rev, the motor will turn in a backwards direction when up stick is applied.  In both modes, the ESC will go into drag brake mode when the stick is pulled back.  I may use a 'cruise control' throttle system here depending on how it feels on the layout.

 

Phase 2:

Engine sounds will be added.  Other incidental sounds (such as brakes, compressor, etc) may also be added at this stage depending on how difficult it is to perform multi-channel audio operations.

In Neutral mode, the throttle lever will cause the engine sound to rev but the motor will not turn and the drag brake will remain on.

 

Phase 3:

Additional functionality such as operating another servo for trailer legs, tipper, ramp, etc. will be added to the steering channel.  This can be accessed by putting the truck into Park mode.

Full additional sounds.

 

There's lots of scope for additional stuff here too but I'll get to that later.

I'll probably use a Hobbywing 1080 Crawler ESC.  It's not the cheapest option but it can be configured with a strong drag brake and simple Fwd/Rev functionality.  I didn't want to have to program around the awkward sometimes brake/sometimes reverse functionality on most ESCs and I hate that when in reverse, most ESCs don't have a brake, they just shoot forward.  Using code I can make sure that pulling back will always stop the truck.  I can also add some throttle profiling so it's not possible to go into full-speed fwd or rev to avoid any panic-inputs causing lots of damage on the layout.  I may even alter the Park mode above so that the motor will continue to operate but at very reduced throttle and with the drag brake always on neutral.

Obviously an ESC with an always-on drag brake isn't going to be easy to drive on the layout, so I'll add some throttle-off profiling to ramp the speed down gradually, or use a cruise control feature to keep the throttle in the last position until the stick is pulled back.

Of course all this functionality needs a rig to power it, so I'll be building a King Hauler day cab from an NIB kit using Globe Liner chassis rails and a cut down cab.  Truck build thread to follow once I've acquired some more parts and cleared up the workshop a bit :o 

Stay tuned - I'll be ordering some parts in the next few days and will start cutting code soon after that.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Coding has begun!

Nothing is in a testable stage as yet as I am literally typing a few lines here and there while waiting for work projects to compile and load.  What I have right now is little more than pseudocode but it compiles OK and in theory it will operate as a dummy MFC, taking input from virtual sources and setting some class values that will eventually be translated into live output.  Things are slowly progressing, but nothing to report as yet.  I anticipating having more than a few teething problems when I eventually push the code into the Arduino and test it on real hardware.

However, I figured it's time for an update and furthermore is time to list the hardware I'll be using for this project.

Elegoo Mega 2560 R3: This is the board I'll be using.  It's a steal at £12.99 delivered on Amazon Prime.

Hobbywing Quicrun 1080 Crawler ESC: I run these exclusively in my brushed crawlers and they're brilliant.  It has a great drag brake and can be configured without any annoying profiles between FWD/REV, so it should accept instructions to move forwards or backwards regardless of the last instruction sent.  Also has LiPo cutoff and a configurable 7.4v BEC output which can be used to power the Arduino through the power jack.  It can also take 3S LiPo and handles up to 80 amps, which gives buckets of torque for pulling heavy rigs, if such a thing is necessary in the future.

Turnigy 9X 8ch transmitter and receiver: I really wanted a RadioLink AT10ii for the extra channels, but money is tight this year and this is less than half the price.  It also doesn't have enough 3-way switches to do what I want it to do, but it's possible to replace the pots with an SPDT switch and some resistors, so I ordered those as well.  I'll post a tutorial on here when I've done it as a lot of the images in other tutorials have disappeared.

There's a bunch of other generic stuff that I've had to acquire, such as a breadboard and some jumper cables for prototyping, of which I'll post more details as they appear in pics.

The radio is on order and should be with me early next week.  I'm not sure whether I'll get started tonight using a Turnigy iA6 radio or wait until the new one arrives.

Watch this space!

 

 

 

  • Like 3

Share this post


Link to post
Share on other sites

This sounds awesome!

I've played around with Raspberry Pi's etc with add on components etc, I don't think it's ever dawned on me to try an MFU.

All the throttle profiling sounds very swish, so I'm looking forward to reading about your progress.

I've still never managed to complete any of my trucks, I'm kinda hoping now you'll inspire me to finish them :D

  • Like 1

Share this post


Link to post
Share on other sites

Quick update: there has been (some) progress!

Code-wise my main project came along nicely during some downtime last week, but the Turnigy 9X has yet to be delivered.  It is expected today.  However I did receive some jumper cables to help prototyping and some 3-way switches to convert the pots on the 9X, which turned out to be two-way switches, hence I won't be converting the pots immediately but testing with the pots in place when it arrives, and deciding later whether to install switches or to move to a command-input method for switching like the Tamiya MFU does.

I was left alone with a toddler all day Saturday and had literally just put her down for a nap when the postman arrived with my jumper cables, so I ran right up to the workshop with the baby monitor in hand to see if I could get some sensible results out of my CC01.  It has a Turnigy i6 radio which is very similar to the 9X, so I figured it was a good place to get started.

First I hooked up the receiver signal terminals on channels 4 and 5 directly to the Arduino and used some very simple code to try to read the PWM values.  The pulseIn() function does the trick well enough for simple projects but I'd seen some advice that it can be quite slow when using it with RC signals, so when I failed to get any sensible values (neutral position / centre position reading around 11000ms, with fluctuations down to 500 or even 0 at odd intervals, and no noticeable change when I moved the switch positions) I moved to using an interrupt library to see if it got better results.  After over an hour of tinkering I got basically nowhere and left the project on the bench when the toddler woke up.

It was a few hours later, as she was having her fragile little mind warped by the '70s ultra-violence of Watership Down and I was busy contemplating the fabulous career of John Hurt, it came to me in a flash of inspiration (in the form of a palm slapping against the forehead) that I hadn't connected the receiver ground to the Arduino ground, so there was no point of reference for the Arduino to read its signals from.

My wife was out all day on a caving trip, so after toddler story and bedtime I dashed straight up to the workshop, sans dinner, to hook up a ground jumper betwix'd receiver and Arduino and retry both libraries.  The result was that both started giving me sensible readings - the more complex interrupt library method seemingly more reliably than the pulseIn() function.  There were some spurious 0 values getting through that I put down to bad connections in the (brand new) jumper cables, as they seemed to occur more often when I wiggled the wires.

I think in the finished version it would make sense to sanitise the receiver inputs so that anything beyond the bounds of normally-expected radio values is discarded and a safe value is substituted when this occurs.  That said, if I'm going to get any kind of glitching, I don't want to use a plain neutral value as the substitute because it might cause the servo / ESC to glitch.  Better to substitute the last known good value unless the incoming bad value persists for more than a few cycles, in which case the channel should be considered dead, a safe neutral value substituted to both steering and ESC, and some kind of warning given that there is a fault.  Ideally these need to go in before the truck hits a layout - last thing I want is for a heavy rig to take off down the layout and smash into thousands of pounds worth of scratch-built airbrushed pride and joy :o 

Anyhoo, having proved that my receiver was giving mostly sensible inputs, I switched over to my actual MFU code and started plugging in some live values.  With a little bit of change here and there I had the steering and mode switch input working as expected (admittedly using pulseIn()) and some form of output working too.  I say 'some form' because the servo was moving, but not how I'd want it to.  At first it seemed like it was going to full deflection and sitting there whining like it was trying to move further, but it took my a while to figure out that it was actually moving more or less fine (the glitchy inputs from pulseIn() weren't helping) but it was whining a lot when it stopped, so it sounded like it was straining.

A Google Search reveals the whining servo problem is most likely caused by low power to the servo.  My servo was operating a GPM steering link in a CC01 chassis with the wheels off the ground, so in theory there was very little load on it.  Also my crawler ESC is set to 7.4v BEC and the servo was being powered by jumper leads coming from the receiver (not the Arduino 5v power output), so again the servo should have had plenty of power to hold a stationary position.  I wondered if it was a speed / timing / resonance issue with the rate at which the Arduino was sending signals, but I had already configured the Send routine to only send when the signal changes and not refresh on every program loop.  I updated to send on every loop anyway, which made no difference.

I had to admit, at this point I was beyond frustrated and starting to wonder if there was something else going on that not even Google knew about, but just before I shut down for the night (it was getting late, it was freezing in the workshop and I hadn't cooked anything to eat yet) I happened to touch the jumper wires powering the servo.  And they were warm.

So maybe my 7.4V BEC was haunting me.  Maybe the servo really wasn't getting enough power because the logic-level jumper wires couldn't handle the current drawn by the servo at 7.4V, even reaching a stationary position.  At that time, figuring I was close to solving the problem theoretically but 40 minutes with a soldering iron from solving it in practice, I decided to call it a night and leave it be.

Sunday I was too busy with family stuff to get another look into the studio but I've ordered some servo plugs and servo wire from the Bay of E, so I will be able to make up some proper cables for the finished project.  I might have time tonight to cut up a servo extension lead just to prove the concept.

In brief - I anticipated some teething problems and sure enough, I got them!  Fingers crossed they don't derail the application entirely...

  • Like 2

Share this post


Link to post
Share on other sites

OK, so I threw another 2 hours into the project last night and early this morning.

My Turnigy 9X arrived yesterday afternoon, so as soon as I'd finished work, cooked some dinner and said farewell to the family, I locked myself in the studio and broke it open for a play.

This thread isn't really supposed to be about reviewing products, but if anyone else wants to follow along later and wants to use the exact same hardware then this might be helpful: the Turnigy 9X is a budget multichannel radio, and it looks and feels it.

I think it's a fair bit older than the Turnigy i6 that I use for other cars, and it shows.  The i6 is a 6-channel (expandable to 10 with a firmware update) compact stick radio, it has a backlit LCD panel, it's not the most intuitive firmware to use but for £40 including receiver it really can't be faulted.  The only reason I didn't use it on this project is because of its limited switch options, but in retrospect the two pots could be replaced with two 3-way switches if I had to.

The 9X looks and feels much older.  It's big - like an oldschool aircraft radio.  It has a lot more switches but as far as I can tell, not all of them can be bound to aux channels, which is a little disappointing.  It takes 8 AA batteries, twice the i6, which makes it a lot heavier, and the stock sticks are longer, meaning a longer stretch to the controls.  The screen is not backlit and almost impossible to read in anything other than directed lamplight - the optional backlit panel is a must.  Some people add the backlight with a switch so it doesn't burn the batteries when in use.  The software is no worse than the i6, that's to say it's fiddly but functional.  Both radios are design for aircraft use so it's sometimes necessary to think in aircraft terms when assigning channels.

In the end, it's a £60 radio.  It doesn't feel as nice as the £40 radio and I'm almost wishing I'd either saved my money entirely and modified the i6, or spent the extra and got the RadioLink.  But anyway, that's beside the point - it works, and I was able to set it up how I want for now, using the pitch trim pot as the mode switch on ch5, and steering and throttle on chs 1 and 2 respectively.

So - onto code and testing.

I bound the receiver and hooked it up to a TEU-101 and a cheap servo.  Everything seemed happy enough so I broke out my jumper cables and hooked the steering channel and servo up to the Arduino and tested it with the last version of the code.  Sure enough that horrible steering servo glitching was still there, along with the bad input values that caused the servo to randomly jump to odd places before settling down.  Also present again was that terrible buzz from the servo.

I figured my first port of call was to switch to the enableInterrupt library to read the pulse values from the receiver.  This is supposed to give tighter timing and be a quicker routine than using pulseIn().  Unfortunately I'd already built all my initial code around a class structure and it seems the enableInterrupt library wasn't designed to be used with classes.  I'm not sure if this is an issue with the library (to be honest the majority of sample code out there doesn't use classes anyway so maybe a lot of Arduino developers don't feel the need for classes) or if it's part of the underlying design of the Arduino controller.  There may well be a neat class-safe way around it but I'm finding the learning curve between C# and C++ to be a lot steeper than I expected and I'm having trouble working out some things that I take for granted in C#.

Anyway, I had to hack away at a lot of my lovely code and rethink a few things but I got there in the end, and I was successfully reporting some neat and sensible values in the serial monitor.  Hooking back up to the output seemed to be a different matter, and my servo was still making a terrible buzzing sound.  I noticed after a while that it was getting seriously hot.

At this point I started experimenting with just sending plain one-off values to centre the servo, and still had buzzing problems.  A huge amount of Googling for hot servo, buzzing servo, glitching servo, rc servo control with analogWrite, etc, finally brought me to a single line of reply in a thread about 8 years old saying (and I paraphrase): Arduino's timing is not compatible with RC servos, you need to use the servo library.

Epic faceplam.  I had been avoiding using the servo library because it uses angle values to control the servo rather than raw pulse values received from the receiver.  My intention was to take the raw input and point it straight back at the output when the truck is in drive mode, or output a static centre position if it's in off or park.  That's not possible.  However it's not entirely a big deal: Arduino has a neat map() function that converts from one range of values to another.  Just perfect for converting receiver pulse values to steering values.

That then led on to another issue that my servo would run full right and squeal like a pig.  It took me a good 30 minutes to discover that this was because of my misunderstanding of lifecycles in C++ - I was initialising the servo using a pin number that hadn't yet been defined!  Once I got my head around that, everything sprang to life.  The steering servo appeared to operate normally and everything seemed happy, although it refused to find a neat dead-centre position, instead glitching slightly between one centre and another.  I've added a small deadzone to my controller code so that when it receives a signal within the deadzone it will output a constant 90 degrees value.

There is also still a little bit of glitching when moving the stick outside of the deadzone.  I need to hook up the servo direct to the receiver to see if that's normal or if it's being introduced by something else.  It could be bad jumper wires or an interference problem, but I'm wondering if it might be to do with the timing used in the enableInterrupt library: AFAIK, the Arduino is single-core and single-thread, and I don't know what priority the change interrupt takes over other code.  The radio pulse timing is calculated by recording the time between pulses, but if the processor is busy with another of its many tasks when the pulse changes, it is possible that it will record a longer time.  I'm going to ask the Arduino to do an awful lot besides control servos.  But I'm not 100% sure about that - I probably need to consult the Arduino forums.

If the glitching is related to something else then I may need to implement some kind of smoothing routine to calm down spurious values.  Obviously this is supposed to be a haulage truck, not a go-kart, so super-fast steering inputs aren't to be expected.  I'll work that out later.

Finally, early this morning I hooked up the speed controller as well.  The TEU-101 is not the perfect partner for the job, firstly because like many basic speedos it has that annoying once-back-for-brake feature but also because for some bizarre reason it needs to be configured with the throttle channel in reverse.  However it all worked perfectly happily from the moment I plugged it in, albeit the wrong way round.

Next trick I think is to tidy up the codebase a bit (with all my recent hackery it's starting to look a bit messy) and then maybe I can get out my breadboard and start hooking up the LEDs.

Once I've done that I'll probably build it into a testbed of some sort and do some videos :D

  • Like 1

Share this post


Link to post
Share on other sites

Good to hear progress is made!

I do not recall the servo issues you are having, when I was experimenting with the LEDs setup and steering limiter based on throttle setting.

I'm still searching for the code, as I seem to have misplaced it somehow. It was a while back. 
I'm sure I did  not use the servo library, but cannot recall how I did the pulseout to the servo, perhaps with a microseconds pulseout function library or something??

Are you sure the servo is functioning normally when it is directly connected to the receiver?
Just this weekend, I had a terribly misbehaving servo. It was simply broken, brand new out of package from China. <_< 

Share this post


Link to post
Share on other sites

I need to hook up the servo to the receiver directly to make sure it's all working properly.  It was only a cheap servo and has never been used before, and neither has the radio, to be fair.  It shouldn't take half a minute to do that but I was running out of time.

If possible I may download someone else's already-working library and see if that works or if I still have trouble.

In other news I was listing all the lights I would need yesterday, so I need to get those ordered.  I'm assuming I can use PWM to vary the brightness of the lights so I won't need to add resistors (I just need to test thoroughly on a breadboard in case I make a mistake and pop any).

I was also looking at some audio libraries and sample code, but I think there I might have trouble.  I was wondering how the Arduino handled multiple timer when it's not a multi-core processor, but it turns out it has various timer chips and these are slaved to the PWM outs.  Ergo if you want to use a timer chip for audio sampling, you tie up those PWM outputs.  I might be simplifying or misunderstanding this slightly as this isn't really my background and I don't fully understand a lot of what has been written about it.

So, it may be that I won't have enough spare timers for the audio I've got planned by the time all the other stuff is done, so I might have to buy a second Arduino just for audio.  There are audio shields too but I don't really know how they work or if they'll require the timers on the Arduino board, and since my Elegoo Mega2560 only cost £12.99 the total cost is still under the budget of something like a Beier system.

It also occurred to me that I'll likely need a smart card to store the audio samples on, which gives me a very simple answer to the question "how do I quickly change engine audio sounds?"

:)

Share this post


Link to post
Share on other sites

Another quick update from me.  Not too quick, mind you, and not too much of an update either, as I haven't been in the studio much this week.

I made a bit of progress on the code today, though.  I had some issues at work and spent most of the day shepherding emails, which was a good opportunity to break out the Arduino IDE and start working through a lot of my //TODOs and get some lighting functionality completed.  The end result is that the first phase of the project is now "code complete".  That means, the code is written but it hasn't yet been extensively tested.

So, what functionality does is currently have?

Drive mode.  Off, Drive, Park.  The ESC and steering will only operate in Drive mode.  In other modes, centre-position is returned on throttle and steering.  Currently controlled by a pot on the 9X on channel 5.

Gear select.  Forward, Neutral, Reverse.  In Forward, up-stick goes forwards, any other position (centre-position, down-stick) returns centre-position value to the ESC.  In Reverse, up-stick returns a reverse value to the ESC so the motor will spin backwards.  As with Forward, both centre-position and down-stick returns centre-position value to the ESC.  This means I have to run the rig with a drag brake, hence why I will be using a HobbyWing Crawler ESC.  Gear is currently operated by a pot on the 9X on channel 6.

Throttle.  As above.  Not having reverse immediately to hand might take some getting used to, as will driving a rig with a drag brake.  Channel 2.

Steering.  Operates as per normal in Drive mode only.  Last time I tested there was some glitching from the servo which I couldn't trace.  May be present in the ESC too but being absorbed by the speedo operation.  More testing required. Channel 1.

Indicators.  Operated currently by the final pot on the 9X.  0 deflection for left indicator, central for off, full deflection for right indicator.  Therefore indicators do not rely on (nor are cancelled by) the steering stick position, so I must remember to engage and disengage indicators manually.  There is currently no hazard light facility.  Channel 7.

Brake Lights.  Brake lights come on when the throttle stick is pulled back.  They do not come on when drag brake is in operation (neutral stick).

Lighting.  Using a two-way toggle on the 9x.  Light modes are Off (all lights off, brake and indicators act as normal depending on mode); Sidelights (brakelights glow at low level, front headlights glow at very dim level); Headlights (brakelights glow at low level, front headlights glow at medium level); and Foglights (as per Headlights but front and rear foglights also glow at full brightness).  There is currently no facility for 'full beam' or flash facility.  Channel 8.

 

So - as you can see, that's my quota of channels used already.  Well, actually strictly no, I've still got channels 3 and 4, which would usually be for trailer legs and gear select, but it's still not a very efficient use of channels.  I'm wondering if there's scope to combine some functionality into fewer channels - Tamiya's cumbersome but effective use of trim sliders is replicable in the 9X by using a dual rate switch, but I want to stay clear of that route if I can.

I've also maxed out my PWM outputs.  If I fit a rear foglight, reversing light and rooflights, I have two pins left for additional servos but that's it.  This is where those RGB LEDs would save a lot of PWM output - possibly 1 pin instead of 8.

I still have plenty of digital outputs, so I'll be able to output parallel data to a second Arduino for audio purposes.

 

I'm waiting on an order of transistors, resistors and a few addictional LEDs that I didn't have in stock.  It might turn up tomorrow if I'm lucky, but more likely Monday.  In the meantime I'll have to test using serial output.  Running regular LEDs directly off an Arduino PWM output is not advised due to the current they pull, so I'll be using an NPN transistor and a 270ohm resistor on every LED channel so I can drive the LEDs from the 7.4V BEC.

I'll get plugging away on the breadboard once the stock turns up but until then it's a case of plugging all the non-LED stuff in and seeing what works :)

Share this post


Link to post
Share on other sites

Updates!!

No worthwhile vids or pics yet, I'll try to get something up soon so y'all can see it in action.

Well - what a few days it's been!  Friday evening I hooked up all 8 channels to the Arduino and tested them independently.  I didn't have my transistors or resistors for testing lights, but I was able to test that the modes, gears and steering worked just fine.  Hooked up to the HW Crawler ESC and a good quality servo in my CC01, it did exactly what it was supposed to do.  The steering didn't feel hugely smooth but tested without the Arduino it was just the same, so I guess it's normal for the location.

I did notice a bit of delay in some areas, and that's when I started reading up on PPM signals and realised I might have taken a wrong turn: PPM transmission can be used to put all 8 channels over a single output on the radio.  This isn't any use for controlling individual servos but it would reduce the number of channels I need on the Arduino.  Furthermore, due to the Arduino sharing interrupts over various input ports, there is a delay when processing lots of channels: not so when using PPM on a single input.

I need to go back to some test code to hook that up but that's a problem for another day.  At least I know it's possible.

Yesterday my transistors arrived, so I got up early this morning while the rest of the house was still asleep and started plugging things into the breadboard.  Just using a single LED, single transistor and a couple of resistors (one to protect the LED, one to protect the arduino) I was able to light up an LED powered by the 7.4V BEC using the PWM outputs on the Arduino.

I had more than a few bugs in code (a typo that mixed channel 7 and channel 8 had me going round in circles for an age, for example) and I had to tweak some constant values to get everything reliable, but tested independently, all the lights eventually started working.

I did have some other issues, too.  I'm using the Hover Pitch, Hover Throttle and Pitch Trim knobs as substitutes for my 3-way switches, and it transpires that if the transmitter is in Aeroplane mode, those knobs interfere with each other.  It took me a small lifetime to spot that.  I don't know if it's possible to unset that in the TX config but fortunately, switching to Glider mode removes the issue entirely.  For a brief moment I thought I was going to have to abandon half of my ideas because I wouldn't be able to get the switch inputs without spending hundreds on a radio.

Anyhoo - the end result is that most of the features are now working.  I still need to test using a single PPM channel to see if it improves performance, I may need to tweak the dead zone a little, and there's the whole issue of audio on a second Arduino board to worry about, but right now I'm happy with progress.

I can't do a full and complete prototype on a breadboard because my breadboard isn't big enough for all my lights, but I'll test every channel individually with the right value LEDs and resistors and if I'm happy I can start soldering things onto a stripboard ready for the first live test.

I really must consider building the actual truck soon too, otherwise I won't have anything to put it in!

Watch this space...

  • Like 1

Share this post


Link to post
Share on other sites

Amazing thread!  I have a breadboard on my desk hooked up to an Arduino Nano and a receiver.  I had thought I'd use it as a bridge between getting signals in and doing some attenuation of the throttle to slow things down for my little boy.  I think I got as far as causing a servo to move all the way, or not at all then moved on to something else.  If it's not rude, do you want to share your code please?  I'd love a play (or even to contribute - we could build a library on GitHub or something)

Now I have gotten my boys ride on car hooked up to an Arduino with some lights, and a siren and faux engine starting noise.  Can definitely help you here - you're right in that you need an SD card, and a little MP3 module that you can ping commands at.  All easy stuff when you find the right one.  The problem comes with things like ongoing engine noises where you're expecting to vary the sound by input (or speed or whatever).  Re-sampling or adjusting the sound isn't something that you can do on the cheap MP3 modules...I've not found a way of doing this yet - maybe at this point you're into a Pi0, with one of those small amp boards.

  • Like 1

Share this post


Link to post
Share on other sites

I'll probably throw my code up onto GitHub once it's past alpha stage.  TBH what I'm building right now is very much geared up to my own personal needs but I'm thinking if I refactored it to use interfaces and factories there's no reason why other people couldn't write their own implementations for their own personal needs.  I love the idea of making a "generic" implementation that just works, but it won't get priority if it's not doing exactly what I want.

Anyway, it wouldn't be that hard for an experienced coder to make new implementations.  The app is essentially split into 3 parts: Input reads input from the receiver.  I've already written two different implementations (pulseIn() and multi-pin enableInterrupts) and I'll be making a third soon (single-pin PPM using enableInterrupts).  The interface will have an Init method that takes the necessary pin data and a GetInput method that returns a struct that holds the values on each channel.  Simples.

Then there's a Control part that translates input to output.  It might be better named Translate (or ITranslator).  This is where most of the custom logic would go.  In my implementation, for example, Channel 2 Up means either Forwards, Backwards, or Nothing, depending on what gear is selected on Channel 6.  Channel 4 Right cycles through light modes (sidelights, headlights, foglights), Channel 4 Left either flashes main beam or turns main beams on depending on the active light setting and how far over the lever is moved.  Some users might want to retain the Tamiya 3-speed gearbox so they'd want a different implementation of ILightTranslator and IGearTranslator.

Finally, Output actually sends the output from the translate class to the servos and other hardware.

To keep it simple (and expandable) I'm using PWM outs to control the LEDs.  This way I can get varying brightnesses for sidelights, headlights and main beams, or tail lights and brake lights.  I'll still need to tweak the values later.  But all this does is puts a PWM value on a pin - it would be up to whoever wants to install this into their rig to work out how to hook up the PWM signal to the lights.  For my application, I use a 270ohm resistor to the base of an NPN transistor.  The 7.4V BEC feed is connected to the collector, and the emitter goes through a resistor and then a string of LEDs depending on requirement.  This means I'm not at risk of putting too much current through the Arduino.

Ultimately I guess I also need a configuration class or struct that gets populated on startup and makes it easier for pin numbers, pwm values, deadzone bands etc. to be modified.  I was having some trouble with #defines being out of scope, and classes being instantiated before #defines has been #defined so I've temporarily declared #defines in the modules where they're used.  Still lots of tidying up to do yet.

But yes - in brief, I'm up for putting the code on GitHub so people can make their own implementations.

In terms of Sound - my Mega2560 still has loads of digital outs available but no more PWM outs, so I don't think I can do sound directly on the board.  I'm not sure I'll be able to use an MP3 shield either and I'm not entirely sure there's an MP3 shield which can do what I want.  I'll have a good look on the market but I think the easiest option will be to use the remaining digital outs to send signals to a second Arduino that just does sound.  Whether I do all the sound in code or hook that up to an MP3 shield is another question to be answered.  Ideally I want multi-channel sound - the engine sound will use at least one channel but I'll want to add a horn, a reversing bleeper, braking effects, air effects, pre-start effects and maybe even a "lights on" warning alarm like the MFC-03 has.  In theory all of that can use a second channel, but I don't actually know how many channels it's possible to do in code.

I won't bother with indicator sounds in my implementation because I always think that sounds lame; you can't hear the indicator sound from outside the vehicle.

Tonight I'll start designing my stripboard layout for the transistors and LEDs.

Last night I used my NIB Grand Hauler chassis rails as a template to drill and tap new holes in my NIP Globe Liner chassis rails, which will be used to make a shorty day-cab King Hauler.  Build starting soon...

  • Like 1

Share this post


Link to post
Share on other sites

This is cool...I've been looking at 3D printer firmware in Arduino recently with the ability to turn things on and off.  If you want to share this earlier, outside of GitHub then I'm happy to see if I can help make it more generic...I think you've done all the hard work, adding some structure should be dead easy!  PM me if you want to go this way, dead happy to help the community as well as for my own reasons.

  • Like 1

Share this post


Link to post
Share on other sites

Update - it's been almost a week since I last posted, and things have started to slow down a bit for various reasons.

I had all the lights tested and working on a breadboard, but when I say "all the lights" what I mean is I used a single common LED, two resistors and a transistor to test that every light channel on the Arduino was working as expected according to the controls.  What I didn't test was that the LED strings and resistor values I'd calculated actually worked with the 2S LiPo that I was using.  Instead I went straight ahead and started soldering the circuit onto stripboard, and discovered last week that some of the channels don't work.

Firstly I think I have some dead transistors.  This is likely my fault - I haven't soldered small components in an age and I only had an old crocodile clip for a heatsink.  I've probably blown some transistors.  A new aluminium heatsink arrived at the weekend, and I've had a week of soldering practice to get in the zone.  I'll replace the bad transistors sometime this week.  I was noticing that on two Arduino PWM channels I would only get 2.4V when outputting a full 255 PWM value (which should = 5V).  I couldn't find a code bug and I couldn't find any reference to this online, so I tested again using the same circuit on a breadboard and it was fine, so I can only assume the dead transistors are somehow holding the voltage low.

The second (and more serious issue) is one of supply voltage.  The Crawler ESC BEC in theory puts out 7.4V when properly configured, but I was only reading 6V with a multimeter.  The LiPo itself was at a storage charge when I started testing and was reading 6.9V at the terminals when I tested last night, so it's understandable the BEC can't output the full 7.4V and obviously there is some internal loss going on that reduces it further from the battery voltage.  I had calculated my resistor values based on 7.4V with the LEDs in parallel, so there isn't enough voltage to operate them if the battery is not topped off.

So I now need make a tough decision: rewire and recalculate for parallel LEDs, or use a 3S battery.  Rewiring would be dead easy as I haven't even started on the LED chains yet and won't do so until I've finished building the body.  I might have to change some resistor values on the stripboard but that's no big deal.  However if the ESC can't effectively put out 7.4V with a 2S LiPo then I won't have enough power to run the Arduino itself.  It needs a minimum of 7V.  Ergo if I go down this route then I need a second battery to power the Arduino, which will take more space.

The other option (and the one I will probably take) is to go the 3S route.  The Crawler ESC can handle 3S and (hopefully) will put a nice solid 7.4V out at the BEC which can power the radio, Arduino and LED breakout board.  Also I bought a new motor/gearbox combo at a local truck meet yesterday - it's a 550 with a planetary reduction gearbox attached, rated at 700rpm at 12V.  It'll probably be too slow at 7.4V so 3S is really the only option.

The real downside to this is cost - I've maxed out January's budget now, so I can't place any more orders until the beginning of Feb.

The good news is that I now have most of the parts I need to build the rig itself, so I can get started on that, or I can start fiddling with audio code.

I took some pics of the setup yesterday but they're on another system - I'll upload them when I can.

  • Like 1

Share this post


Link to post
Share on other sites

Another quick update - the project got parked for a little while for various reasons, mostly because I found I was constantly shuffling things around to make space for other stuff.  My King Hauler drag racing truck is now well underway, so soon it'll be time to start packaging the electronics under the hood and working out where everything is going to go.

I had a night to myself last night, so I dragged up the old code and figured I'd try to implement a single-channel PPM interpreter instead of reading all 8 channels separately.  Due to a limit in the number of hardware interrupts on the Arduino, there's a small delay when reading multiple channels using an interrupt.  I can't explain it technically as I don't fully understand but the solution is to connect a single digital pin to the PPM output on the receiver.

I downloaded some sample code that promised to make it all work in just a few lines with no external libraries, but I couldn't get it to work.  I figured it must be a problem with the radio config, and despite the 9X clearing saying "PPM" in big LCD letters on the front screen and the iA8 receiver having a PPM output, I found a lot of websites telling me the 9X doesn't do PPM.  Well, the truth is that it does.  I eventually downloaded a different library:

https://github.com/Nikkilae/PPM-reader

and using the sample code on the site, I had it reading values from the receiver and outputting them in the serial monitor in a matter of minutes.

It also didn't help that I'd tried changing the stick mode on the transmitter while trying to get the previous PPM sample code to work, which wiped all the aux channel config.  Lame.

Anyway, once I had the sample code running it took a matter of a few minutes more to port it across to the MFC code and replace the very bulky 8-channel interrupt code.  So now I'm using far less input pins and in theory I should have more reliable output.  I couldn't test it fully as I didn't have space to get my CC01 set up on the bench but the new HK Crawler ESC and LiPos have arrived for the King Hauler, so I should be able to start testing the rig on the bench fairly soon.

Still not started on the audio system yet...

Share this post


Link to post
Share on other sites

Another update - bit of a long and technical one, I'm afraid, but I will include a summary at the end.

So as I mentioned elsewhere, I got the system hooked up on the Drag King a few days ago but I was having some trouble with a glitchy steering servo.  I actually hooked up the radio to the servo without the Arduino and still had some glitching problems - I tried a different servo, different channels and would have tried a different Rx but I don't have anything that works on the 9X's protocol.  I figured the issue must be in the Tx/Rx itself so I conveniently decided to leave it for later.  I did read in a few places that the 9X can be prone to interference and I was running a video baby monitor at the time, which is famous for glitching everything in the vicinity, so I didn't worry over much.

Last night I brought the whole assembly into the studio and plugged it into the laptop to see what was going on.  This time where was no baby monitor but the glitching was horrendous.  I wouldn't have wanted to drive it.  When operating the steering the servo would jump between positions and never sit still when centred.  I'm using the PPM port on the Rx, so I was able to hook up a second servo to ch1 on the Rx to see if the glitch was being introduced by the Arduino or if it was on the channel all along.

The result: the servo on the Rx worked fine.  I tried swapping the servos over again and tried different channels but basically, however I hooked it up, I was getting glitching effects through the Arduino that I wasn't getting directly from the Rx.

I checked and checked again that the wiring was hooked up correctly, that the earths were good and that the servo was getting plenty of juice from the LiPo.  Everything looked just fine.

Then I noticed something really odd.  As a reminder - I'm using the servo.h Arduino library to control the servo, and it needs to be fed a value (in degrees) of between 0 and 180 to set the servo to the specified angle.  I've got a map() taking place to turn the incoming PPM values for steering and throttle channels into a servo position, and I'm outputting said angle to the servo.

Here's the odd thing: I had the Arduino Serial Monitor set up to list the input values coming form the receiver and the angle values going out, and the outgoing values were not changing.  Yet, the servo was glitching.

So, according to my code, I was outputting a constant 90 degrees into the servo, and yet the servo would happily sit there, at idle, twitching twice per second.

I did some searching online and found various threads reporting this when using servo.h and some that alluded to an issue with watchdog.  I had to look that up, but watchdog is essentially something runs on the Arduino firmware and checks that it hasn't crashed.  I think it's designed to reboot the Arduino if it stops working so that an automated application will not fail if the controller stops responding.  It polls the interrupts every 500ms, which coincides nicely with my glitching.

Anyhoo - various attempts to disable watchdog made no appreciable difference.  Disabling timer 0 caused my PPM inputs to stop working.  Around this time I was ready to throw my teddies out the pram and walk away, but I was reading elsewhere about config for servo.h and I decided to play around with settings.  Hold this thought.

Another issue I've had is that I get way more servo throw through the Arduino than I do through the Rx, so the extend that the servo actually twists the axle on the leaf springs at full lock.  I had planned to fine-tune the endpoints later but something jumped out at me while I was reading: I was mapping values of 1000 to 2000 to values of 0 to 180, but the default configuration for servo.h is to assume 0 is ~500 and 180 is ~2500.  That's actually beyond the range of most servos.  There's an optional overload on the servo init method that sets the endpoints.  Once I'd set the endpoints to 1000 and 2000, the glitching was greatly reduced.  In fact whatever interference seemed to be causing the 500ms twitch was gone.

As I played more with the Arduino, I began to notice more things.  Notably, the servo would never move smoothly as I moved the stick - it would jump between positions.  Comparing input to output in the serial monitor I could see I was losing a lot of resolution by converting from PPM to degrees, so I got rid of the PPM-to-degree map entirely and replaced servo.write() with servo.writeMicroseconds().  That way I was writing out exactly what was coming in (minus some deadzone and mode change stuff).  Result: move smoother servo operation.  There was still some jumping going on, but much less than before.

But there's more to come: I also noticed I'd put in an arbitrary delay of 20ms in the main loop.  When writing for most platforms it's good practice to throttle any loop with a delay to prevent it from hogging all the system resources, but as the Arduino is only a basic controller and isn't multithreaded I figured maybe this wasn't necessary.  Indeed - if I increased the delay to 50ms or 200ms the jumping in the servo got noticeable worse.  Of course it did!  The longer the delay in loops, the lower the resolution in converting a smooth input signal to an output.  By removing the delay altogether I was able to increase the resolution just slightly better than with a 20ms delay.

I might have to do some debug logging to work out exactly how many loops per second I can achieve because it's not perfect.  I can only guess that, at this point, I have reached the limits of what I can do with an Arduino: it's only designed for basic applications and it's doing quite a lot of unit processing between reading the PPM input and sending outputs to various pins.  The PPM library I'm using is a closed box and I don't know if there is anything in it that could affect performance.

Anyway - by logging the loop speed I might be able to do some performance tuning and speed up the loop for better resolution.

And again - I still have not yet looked into the audio at all.  I was intending to use the current MFC code to issue a series of commands over serial that a second Arduino could read as instructions to play audio - as in a master/slave config.  I'm now wondering if I should duplicate my current code on the second MFC but replace the servo and light code with audio code.  That would reduce any additional processing I need to do on the master Arduino.

The other alternative is that I port the code to Python and see if I get better performance with a Raspberry Pi or something else that has more power.  They're a bit more expensive but not prohibitively so.

Yet it could be that there's no performance problem at all and the glitch is elsewhere, and I'll find it if I keep digging and debugging...

Another thought I had is that the glitching probably looks a lot worse than it is because the axles are lifted off the ground by old TLT tyres and the stock setup has so much play that the wheels visibly rock with every movement.  Once down on the ground the problem will hopefully not be so noticeable.

Summary

Hooked up the latest version of the code to the Drag King and had some servo glitching.  Not a fault with radio or servo.  Vastly improved by transmitting PPM values direct instead of converting to degrees for the servo library but still having resolution issues that appear to be caused by slow performance.

Play in steering makes it look a lot worse than it probably is.

Still unsure when I'll do an on-the-ground test drive as I haven't set up any wiring that allows the Arduino to be mounted safely off the ground and away from bare metal.

  • Like 1

Share this post


Link to post
Share on other sites

OK - update!  I took the Drag King along to the Bournemouth RC Trucker's meet yesterday to give it a rest-run on the layout and see how well the steering rate and overall speed worked.  I would liked to have known how long the 2200mAh pack lasted just driving around with no trailer and very little bodywork, but alas it was not to be.  The glitching problem came back to bite me.

So... Before I left for the event I gave the truck a full-throttle test in the garage.  I don't have a lot of space so couldn't do much full-speed running, and I wasn't too worried when the motor cut out before engaging again.  I'd been using the 4250mAh 3S pack for a while just for testing, and sometimes it would be left switched on for an hour or more while I updated the code.  I figured it was probably hitting the LiPo cutoff in the ESC.  No matter, I had two fully-charged 2200mAh packs to take with me to the layout.

Unfortunately the issue on the layout was worse by a magnitude of many millions.  If I drive the truck at more than partial throttle, it would cut out, then start again.  It was like there was some cut-off in the ESC that was making it temporarily stop.  I hooked it up to the laptop to see what was happening.

Sending the input values for all 8 channels down the serial port for debug purposes, I was able to watch what my transmitter was doing on screen and compare it against the output data sent to the servo and ESC.  Sure enough, at random points, the code would send 1500 (neutral) to the ESC instead of the incoming value.  Something in my code was telling it to go neutral for just one loop, and the ESC would slam on the drag brake.

Trying to interpret 10 columns of 4 figures each as they scroll past at Arduino loop speed isn't easy, so I added some more debug info to tell me, for example, when the truck was in Forward, Neutral or Reverse, when the truck was in Park Mode, Drive Mode or Function Mode, and then the throttle stick was in the deadband.

Result?

Randomly the truck would go into Neutral gear.  That means CH6 was receiving a signal in the deadband.  I could clear see values of 1500 - 1503 coming in on channel 6 at random intervals.  Ch6 is what determines the gear - with the knob turned fully up it is in forward gear, in the middle it's in neutral and fully down it's in reverse (I intend to replace the knobs with 3-way switches as soon as they arrive!)  When the gear is Neutral, the Arduino will send a constant centre position signal to the ESC so it can't drive anywhere.  In effect the gearbox was randomly selecting neutral and the ESC's drag brake was coming on.  The knob itself wasn't being moved and I could see no valid reason why it might be giving incorrect data.  I'm using a 3rd party library to read PPM data from all 8 channels at once and I don't know exactly how it works.

Anyway, I figured if the problem was specific to channel 6, I could add some damping code to temporarily work around it until I could figure out what's going on.  I changed it so the gear would only be changed if the request to change lasted for 4 cycles or more.  That meant any 'glitch' on channel 6 needed to be of significant duration.  Code changed and uploaded, the problem totally persisted.  Aargh.

Debug data told me the truck wasn't selecting neutral any more (or actually it was, but not as often as before).  However the throttle channel was also returning to 1500 from time to time.  Well, I don't want to add any damping code to my throttle channel.  After all, if I let go of the stick, I want to be sure the truck is going to stop.

So, it looks like there's a significant problem somewhere down the line.  Right now I don't know where that is.  I tried to find it before my last post and had no luck, but I'm going to have to look deeper to see what I can find.

I've been trying to think of possible causes and solutions.  Right now the following is in my head:

Radio is faulty.  I've seen other posts complaining about glitching on the Turnigy 9X.  I can test the radio without any Arduino hookup at all.  If I power it from a BEC and plug in 8 servos, I should be able to hear any of them glitching.  If it's faulty I can either return to HK for a refund or consider fitting a different radio module- some people switch to FrSky modules which are supposed to be better.  I'm not sure if my other Turnigy radios have a PPM channel but if they do I can hook up and test fairly quickly for any glitches (although I can't do a full test as my other radio doesn't have enough inputs with the right input range).

Arduino supplying insufficient voltage to receiver.  As receiver is rated only to 6v but the ESC is putting out 7.4v to power the Arduino.  The Arduino has a 'clean' 5V output which I'm using to power the receiver.  I'll test it with a multimeter (I got a new one for my birthday!) and see if the voltage is sufficient.  If not I'll risk powering it from the 7.4V BEC - actually I plugged the ESC direct into the receiver last week to test something else and forgot to change the BEC back to 6v, and it survived with no apparent ill effects, so I think it'll be fine.

Problem exists only on PPM channel.  Hook up all 8 channels to my old interrupt code and see if the problem persists.  It might be an issue in the single-channel PPM library or it might be a fault in the radio or even a bad connection.  If the problem persists randomly across all channels when hooked through 8 channels then it's not specific to the PPM output or to the PPM code.

Arduino hardware is introducing glitches or interference.  This will be hard to trace as it's not easy to log in realtime what the Arduino is doing.  However I could hook up the Arduino to the PPM channel and leave 8 servos plugged in to the other channels.  If I start to see glitching as soon as I hook up the Arduino, there's something odd going on.  I had an issue a week ago whereby the steering servo would glitch every 500ms which might have been related to a background service on the Arduino interrupt, but I couldn't make it stop using any of the sample code.  Then randomly it stopped all by itself.  It's possible that either the Arduino or all the mess of jumper wiring surrounding it is picking up interference and introducing glitches where no glitches were before.  I'm not really sure what I can do about that - in a final product the wires will be very short and I can shield them along the chassis rails, but I'm not sure how I'll shield them for testing purposes.

All-in, I'm kind of at a stuck point and not really sure what to do until I've tested some more.  An oscilloscope might be useful...

  • Like 1

Share this post


Link to post
Share on other sites

SUCCESS!!!

An hour ago I was almost ready to give up and order a Raspberry Pi, but I kept plugging away and trying different things until I randomly stumbled across a solution.  I'm reluctant to call it a proper solution since I don't know why it's a solution, but at least I have a working MFU, and right now I don't need to beg, borrow or steal a second Tx/Rx combo to test with.

First of all, I spent well over an hour looking for alternative PPM libraries to try, but they either said they could only handle 4 channels, or they were a pin-per-channel setup, or I couldn't get them to compile.

Secondly I went back to the PPMreader documentation and studied carefully for anything I couldn't understand.  It seemed possible that if any channel had an error condition then it was likely to output a default value of 1500 (servo centre) which is exactly what my problem is: some channels randomly go centre.  However it seems the default is 0, and I don't seem to be getting that condition.  (I may not be reading the code correctly but either way, playing with defaults didn't seem to be helping me).

There is an option to change the max error value in the library - it wasn't clear from the documentation exactly what that would do, and I couldn't quite get my head around the code, but changing it from the default (10) to 5, 20 or even 80 made no difference at all.  Or at least, none appreciable.

After having no joy there I decided to do some more reading into how interrupts work on the Arduino.  We very briefly covered interrupts on a microprocessor design module I did at college over 20 years ago, but not enough that I really understand what they do.  However I was aware that the Arduino only has a limited number of interrupts and that they (somehow) affect and/or affected by timer operations (like millis() and delay()).  So it turns out that the Arduino Mega2560 has 6 interrupts; 0 and 1 are on pins 2 and 3 respectively (which I am using for light outputs), and 2, 3, 4, and 5 are reversed across pints 21, 20, 19 and 18 respectively.  I have been using int.5 on pin 18 since I've started playing with this particular library.

I figured it was worth trying a different interrupt, so I switched to pin 19.  I still had just the same amount of glitching.  Randomly I figured I'd go direct for pin 21 on interrupt 2, and all of a sudden everything started working.  No glitching.  I even took the rig out into the workshop and drove it around.  Several minutes testing and no glitches at all.

I even went back into the code and pulled out all my smoothing subroutines to improve response, and still had no issues.

So, I am assuming that something in the Arduino is using interrupts 4 and 5 (or the timers thereattached) and causing timing issues and glitches, but interrupt 2 is currently unused, or at least not used so much that it can't respond.

Having got it working without glitches I decided to start stripping out a load of debug code that I'd put on the Serial connection, and suddenly I found the resolution in the steering went way up.  As in, the jerky steering caused by slow loop operation was almost butter-smooth.  Wow.

My problem, it seems, is that I was making lots of calls to Serial.print() in every loop.  I would print the channel value for each of the 8 channels, then some debug info about the mode and gear and throttle stick state, and then printing the values sent to the ESC and steering servo.  Each chunk of data would be a separate call to Serial.print().  Of course, I keep forgetting that it's a microcontroller, not a microcomputer.  It can't multi-task and there's no separate onboard processor for sending serial data - it must be done by the Arduino itself.  Generally it shouldn't cause a problem but I was transmitting enough data to full the buffer, which then caused the Arduino to pause while the buffer was emptied.  Increasing the baud rate from the default of 9600 to the max of 250000 made a big difference but a bigger difference was made by sending no debug info at all.

So, there we have it.  Right now the truck is entirely driveable.  There's still a fair bit of work to do to get the lighting system working properly, it has a few bugs, and my power board isn't working properly yet, but at least the major showstopper is sorted, which has opened up the gates for a whole new round of work.

Stay tuned! :D

  • Like 2

Share this post


Link to post
Share on other sites

Another quick update - mostly because I'll forget things if I don't write them up now...

So, with the glitching issue hopefully resolved, I started tidying up the code.  I've added a readme.md file and I'm starting the long haul of adding all the important notes in there, as well as a huge list of todos.  I've cleaned up the comments in the code and removed bits that are no longer needed.  I've renamed some inconsistent or generally misleading variable names and I've added new structs to simplify moving data around the app.  Mostly this was a nose-in-code operation, but first thing this morning I figured I'd hook up the truck via USB again to make sure nothing had been broken by my amateur tinkerings.

Lo and behold, some twitchiness in the steering servo had returned.  ESC appeared fine but steering was no longer supple and smooth as it had been previously.  I figured if anything it should be better, as the code is more streamlined and lots of unused variables have been removed.

On closer inspection, the issue is...  Well, odd.  I'm not sure I fully understand.

Currently the wiring is a bit of a mess (I'm using male-to-male jumper cables peeled from a ribbon) but it's sort of like this:

ESC plug goes into a servo Y lead.  One output of the Y lead provides power and ground to Arduino VIn (via the 7.4V BEC on the ESC) and also connects to Arduino pin 11 (output) which controls the ESC.  The other output of the Y lead provides power and ground to the steering servo.  The steering servo's PWM input (white wire) is connected to Arduino pin 10.

Arduino 5V is a regulated 5V power output, which I use to power the receiver (I have accidentally overdriven it with 7.4V with no ill effects but it's not rated beyond 6V).  The receiver is also connected to a spare ground on the Arduino.

So we have ESC powered directly by 3S LiPo, Arduino and servo powered by 7.4V from the BEC, and receiver powered by 5V output from the Arduino.

With me so far..?

When hooked up to the PC via USB, the Arduino doesn't need the VIn connection, because it gets its power from USB.  So I unplug VIn.  Actually the Arduino is supposed to have a safety feature to avoid sending voltage back into the USB adaptor and damaging the computer, but given how much my laptop cost and how much I rely on USB for other stuff, it's not worth taking the risk of blowing either a USB port, the USB daughterboard or even the entire motherboard - so I never connect to the laptop if VIn is connected.  (I might put some safety feature on the finished product whereby I can't get to the USB port without disconnecting VIn, like having a switch that covered the port).

So - here's the odd thing:

While testing this morning, operating the steering servo causes the LEDs on the Arduino board to dim.  I tested it today with all the lights out.  My first thought was that I had a mistake in my wiring and the Arduino 5V was powering the servo too, but that's not the case.  I've checked and checked again, the Arduino is only powering the Rx.  It doesn't happen when operating the ESC, only the servo.  I've tried swapping pins but the same thing happens.

My second thought was that the servo PWM in was somehow drawing a large current, causing the board to brown out and putting at risk of blowing a pin (they're only rated to around 40mA and are known to fail if over-currented).  So I hooked up my lovely new multimeter to discover that it's only pulling around 30uA.  That's a tiny current and well within what the Arduino should be able to handle.

I was hooked up via USB at this point, so I decided to unplug and reconnect to the ESC 7.4V supply.  Lo and behold, the problem disappears.

I think I need to do some more probing when I have time, mostly to be sure the Arduino is getting sufficient voltage from USB and that the outputs are delivering the required voltage, although I don't have an oscilloscope so there'll be some guesswork involved.  I'll also try a different servo just in case there's something wrong with this one.

So - there's another reason why I might have noticed some jittering in the steering servo when playing over USB...

Still loads more to do, but I'm hopefully I can hook up the lighting board again on Thursday evening and see if I can get all the lighting working :)

March begins soon also - I'll have a fresh budget to buy a few bits I need to do the next steps, including a tiny Arguino Mega2560 board that should fit under the battery tray and some new low-profile connectors for the lighting board.  It may not be too long before the complete unit is properly driveable, even if there is plenty of other stuff to finish :D 

  • Like 1

Share this post


Link to post
Share on other sites
36 minutes ago, Mad Ax said:

Currently the wiring is a bit of a mess (I'm using male-to-male jumper cables peeled from a ribbon) but it's sort of like this:

ESC plug goes into a servo Y lead.  One output of the Y lead provides power and ground to Arduino VIn (via the 7.4V BEC on the ESC) and also connects to Arduino pin 11 (output) which controls the ESC.  The other output of the Y lead provides power and ground to the steering servo.  The steering servo's PWM input (white wire) is connected to Arduino pin 10.

Maybe it would be usefull to put some pictures here of the setup. I believe you use an Arduino Mega 2560? And what ESC do you use?

Can you use a multi-meter to verify the output of the ESC BEC voltage going into the Y cable? I would expect this to be typically 5V , 5.6V or 6V (thats the values I've seen in most ESCs). Not 7.4V which would be direct battery voltage.

If the ESC indeed outputs 5V to the Y lead, It should not be connected to Vin as Vin is the pin for the external power supply, rated for 7 volts up. This is because there is a power regulator on the board that will convert the Vin voltage to 5V. But if the ESC BEC voltage is already 5V, this regulator will not function properly and the arduino may show all kinds of unexpected things due to brown-out/undervoltage. Especially if the steering servo starts drawing current when moving.

If the ESC BEC voltage is 5V, connect it directly to the board +5V pin which is a few positions toward the power connector I believe.
If the ESC BEC voltage is higher then 5V, but not at least 7V, connect it to the 5V pin via a few diodes. Each diode should drop the voltage by 0.6V.

  • Like 1

Share this post


Link to post
Share on other sites
3 minutes ago, Ray_ve said:

Maybe it would be usefull to put some pictures here of the setup. I believe you use an Arduino Mega 2560? And what ESC do you use?

Can you use a multi-meter to verify the output of the ESC BEC voltage going into the Y cable? I would expect this to be typically 5V , 5.6V or 6V (thats the values I've seen in most ESCs). Not 7.4V which would be direct battery voltage.

The ESC is a Hobbywing Crawler ESC, which has an optional 7.4V BEC (for high-torque steering servos, winches etc).  Running with a 2S LiPo it only outputs around 6V (especially as the LiPo voltage drops) but I'm currently using a 3S LiPo.  I haven't actually had a chance to measure the BEC voltage yet to confirm that it is giving me the full 7.4V but the Arduino runs quite happily on the BEC power supply and I don't have this brown-out issue when on BEC voltage.

The Y-lead means I am also powering the steering servo from the 7.4V BEC, so in theory the Arduino output to the steering servo is only sending a 5V PWM signal.  I've measured the current - it's between 25uA in the centre, up to around 33uA when on full lock (presumably a longer PWM pulse = higher average current).

Notably, this only occurs when the Arduino is powered by USB.  (Note that in this configuration the servo is still powered by the 7.4V BEC).  I need to check the voltage on the board to make sure the USB lead is providing it the expected 5V.  Even so, the current to the servo is so low that I can't see how it's causing a brownout on the board.  Steering operation doesn't trigger any lights or other functionality at the moment.  It's rather bizarre but ultimately not a major problem because it only happens when hooked up to the laptop, not when actually running on the ground from BEC power...

Share this post


Link to post
Share on other sites

Found the specs of the ESC, and indeed, it should work per your description.

Strange that it glitches while USB power is also present, that should not make any difference. When power by USB, is the ESC still connected and on and hooked to the battery?

Share this post


Link to post
Share on other sites

Yes, when the Arduino is hooked up to the USB port, the ESC is still switched on and supplying 7.4V to the servo.  It is connected to the Arduino via Ground but the 7.4V supply to the Arduino is unplugged (I don't want to risk damage to the laptop USB port).

Share this post


Link to post
Share on other sites

Not a lot to add today, other than that I did some fine-tuning of the current version of the code whilst hooked up to the rig last night.  I'd say it's probably now reached Iteration 1.0 and is a functional, usable device.  I hooked up to a breadboard with some plain white LEDs and resistors to test all the light functionality.  If there is one obvious bug right now, it's that the sidelights come up when the Arduino boots - probably a one-liner in the Init() method to fix that.

Driving modes work as expected.  In Park mode, everything is off; in Drive, it works.  In Function, nothing really happens as there are no functions yet (and I don't need any for the Drag King just yet so I likely won't add any until I'm ready to outfit another rig).

Fwd/Neutral/Rev simulated gears work as expected.  The reversing light comes on when reverse gear is selected.

The brake light works then the throttle stick is pulled back.  At present back-stick does nothing else, since the ESC has a drag brake - the truck stops just as quick if I let the stick return to centre as it does if I pull the stick back.

Indicators are on a toggle switch and work as expected.  There is no auto-cancel and I hadn't planned to add one as I'll mount the toggle switch in a convenient place on the Tx.

Headlamp switch works.  Moving the left stick to the left cycles through modes: sidelights (headlight low intensity, brake light low intensity), headlights (headlight medium intensity, brake light low intensity), foglights (as per headlights but front and rear foglight outputs high intensity) and 'off' in which heads, tails and fogs are all off.  If the headlights are off or on sidelight mode, moving the left stick to the right will cause the headlights to go to high intensity until the stick is released (i.e. "flashing" the main beam).  If the headlights are on headlight or foglight mode, moving the stock to the right will latch the main beams on or off.

Roof lamp output works when all headlight functions are on.  I haven't bothered with a 'speed indicator' function like the MFC-01 since that seems pointless so me.

However, I found driving with an instant drag brake to be something of a pain, and the steering (now without any smoothing) is too fast for a rig, so my next plan (maybe tonight if things are quiet) is to add a customisable inertia to steering, acceleration and deceleration, so it drives more like a rig should.  I'm almost tempted to use the throttle input like a real throttle, i.e. it determines rate of acceleration rather than top speed.  I'll have to drive it carefully around my patio to be sure it's not too hard to drive and I might have to turn my mathemetical brain on to work out where max speed will be at a given throttle position.

Deceleration will be a nice linear ramp down when the throttle is released or lowered, with the linear rate increased when the lever is pulled backwards (a la applying the brakes).  As a safety feature, if the lever is pulled fully back the output will return to centre position to apply the drag brake immediately so it's always possible to stop the rig on the layout.

I'm considering eventually utilising the switch in the 5th wheel, and applying two sets of inertia figures - the truck will accelerate and brake slower with a trailer attached.  But that's a fair way away just yet.

 

Other stuff I don't have but probably should for release:

horn function (I need to define the input although there is currently no audio functionality at all)

hazard indicators

Possible updates: Since it isn't possible to independently switch front and rear fogs, I may condense foglight output to a single pin.

  • Like 1

Share this post


Link to post
Share on other sites

Great thread, I'm following with interest and even understand some of it.

The Turnigy 9X is a rebranded Flysky product right? The rx may happily handle 8.4v input. I have the fs-ia6b rx and thought they were rated up to 6.5v. Then I looked at them more closely and realised they say 8.4v. I checked banggood again and the picture was different, it said 6.5v on the rx, and the description said 6.5v. I asked the question and they confirmed they are now 8.4v and updated the specs in the descriptionp but not the picture. I've had a look at others and it appears that Flysky rx are now rated at 8.4v. At least they're cheap if not!

Share this post


Link to post
Share on other sites

I'm pretty sure it's rebranded FlySky, although it's a lot older design-wise to the fs-ia6bs and the like.  I have the Turnigy i6 transmitter which I love, I almost bought another one of those for this project but I wanted more three-way switches.  I was disappointed to find out that the actual 3-ways on the 9X tx can't be bound to channels, they are for aero stuff only, but there are 3 pots that can be bound to channels so I'll be replacing those with 3-way switches as soon as I can get some.

Anyhoo, I digress.  I did temporarily hook up the receiver to 7.4V and it was fine, so I might be able to run everything that way.

I have ordered two new Elegoo Mega2560s, this time in black.  I had intended to buy the Mega Core, which is basically a Mega2560 with a smaller form factor and DIY pins, but it doesn't have a VIn, only a 5V, and a proper 5V convertor would take up as much space as I save under the bonnet.  So I've modified the design a bit to try to get more space for two full-size Arduinos.  It's going to be a very tight fit :o 

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...