Arduino code for fusorpi slaves

Well, it appears there's no really good way to do this here. This will contain various bits of code used to support the fusor, which presently includes everything from embedded 8 bit uP code to stuff to run under Linux in some HLL (often perl) to interface-specific stuff for commercial hardware, sysadmin tips and setups, and running on whatever machines I have in the tree here. So any one piece might fit some other category too, but...there's no pigeon-holing even computer science without losing the app-specific stuff and inter-relations of it all in a specific usage.
Forum rules
Code sharing for fusor data aq and control software

Arduino code for fusorpi slaves

Postby Doug Coulter » Sun Mar 05, 2017 1:56 pm

I should probably split this up further,'s a dump of some useful stuff in relatively compact form. I do all my final development of slave arduinos on the pi they are slaved to. fusorpi happens to be running version 1.6.11 of the IDE, which is fine for this - these are both unos. (later versions of the IDE should work too, but there was no point putting them in when I'm busy with other stuff)

As is often the case, as I went along I changed some things about the master<>slave communication protocol I use, and of course did NOT go backport all of it, so examples of both are here, and both work fine in this lashup, which has the arduinos simply plugged into USB ports on the pi (though I have a separate switcher supply in that box that makes ~ 7.5v to power them so their a/d references are not dependent on the pi power and cable resistances).
My fusor-dedicated arduino sketches (for now)
(674.46 KiB) Downloaded 22 times

I initially wrote both of these sketches to be time-synced by an interrupt that would start them together, and reset their reported milliseconds since start based on the same zero time. I call that a clap-board signal, kind of like what Hollywood uses.
Well, we've had some "interesting" high energy events that would sometimes false-reset them to zero time. That was a bummer as my plotting program that plots from the MySQL database on the fusorpi just asks for "most recent data" using that time value, so if it happens, plot stops working (and is the reason for the "munge time" checkbox on that program so I could see older runs better). The newer version of each, once started by this interrupt, simply records further ones and reports it in "comment format" which is any line that starts with a # in the serial output, and which is parsed correctly by the fusor pi master control code and logged - nice to know if say, some data might be suspicious since obviously there was some REALLY LOUD interference in that sampling interval. We don't throw away anything, we just mark it as maybe dodgy for later analysis. The later versions of the two sketches marked with _FC at the end of the name are so modified.

And in general the religion of "always keep the raw data" is followed here. Any unit conversions and so forth are done later - what goes in the data store is "as is" to the extent possible.

The DatAQ_FC sketch is generally useful for data acquisition. It has the simpler control protocol from the host, which is laid out in the HandleHost() subroutine. A ! resets the arduino. A p toggles pause. A c means "clapboard" if you want to force that from software from testing, otherwise a falling edge on pin 3 fires an interrupt to start things rolling. Though both ends of the comm are set for 115200 baud, it doesn't seem to matter a lot...This version just reads one character and does the command if it maps to something it knows how to do, otherwise it just ignores input on the usb serial port.

Two counters are supported. One is hardware and can go really fast (MHz). The other is just an interrupt and I wouldn't use it for really fast signals, in our lashup it's hooked to a geiger counter which is self-limiting as to rate.
All of the a/d channels are sampled, and to get better precision I sample them a lot and average the results, or well, simply sum them, so there's more bits than are really there on the a/d converter. Some of them are good...
I use a 10k series resistor and a .1uF cap to ground on the screw shield board for this arduino on each channel, which lowpasses these a little and also makes them almost burnout proof.

So, if you burn this into an uno, fire up the serial monitor at 115200, and send it a c, expect a bunch of numbers to come out in lines at 10 hz, which is our basic sample rate. These are all in time sync and the line starts with how many milliseconds have elapsed since the clap signal (which might not be zero for the first sample - but it'll be correct).

This sketch is a decent place to start for basic arduino uno data acquisition and logging, I've used it more than once here. You could remove the wait for clap logic if that's annoying in your application.


The other sketch is more fusor-specific. uFuseControlFC does some data aq (the idea being having the data right there to do some automation with later on) but mainly is there to control the gas inlet and outlet solenoid valves.
Of course, the fusorpi also writes any acquired data down in the database, which means sometimes we have data from the same sensor from two arduinos. I don't think that's a bad thing.
This one uses some logic level FETs and associated damping diodes and so on to handle the solenoids, which are 24v models we drive at around 40v to make them work faster so we can get gas control in finer increments (And it's never fine enough). We use "batch mode" here for runs - we let in gas, run, maybe adjust this way or that, then pump it all out at the end. Works for us.

This also uses the clapboard hardware signal, or a c sent over the serial port to start it. This sketch does use a somewhat different commuication protocol I developed later for allowing multiple arduinos to share one input serial line (ttl serial) and wire-or one serial ttl line back to the main controller/host. Obviously baud rate does matter for that (I put a post about this up on Adafruit's forums). So, this adds a requirement for a unit address, which for this sketch is 5 (ascii), It also requires a /n at the end of a command, and that the command complete inside some arbitrary timeout I set. I figured of the things I might be controlling with this might create issues if they went off half-cocked as it were, so I added some error resiliance. Absolutely not required for the fusor, but more trouble to change than to just shove a 5 and a linefeed onto commands in the master control software.

Same idea for the a/d as the other sketch, but here we also have timed pulse outputs for the gas solenoids, and a PWM (I used the fast one) output to control our ion HV supply (after lowpassing the pwm). I saved some of the tunings in the arduino eeprom, not sure whether that was best or not, but it is what it is.
Posting as just me, not as the forum owner. Everything I say is "in my opinion" and YMMV -- which should go for everyone without saying.
User avatar
Doug Coulter
Posts: 3038
Joined: Wed Jul 14, 2010 7:05 pm
Location: Floyd county, VA, USA

Return to Fusor support

Who is online

Users browsing this forum: No registered users and 1 guest