I wired up the second pump, which runs at a different voltage to the first pump, to Sparky, so we now have boards with voltages of 48v, 24v and 12v. I don’t think I’m going to be looking at 6.
I /think/ the 12v is 12v. I just got hit by a nagging suspicion that’s my stepdown to 24 and now I just don’t know. Balls. I mean, I know at the time that I tried to make a stepdown and then I found the board thta did it… but did I know at the time or did I just remember knowing? Doppleballs.
Category: Sparky
Sparky – resistor array
Sparky’s first spark-board resistor was 100ishR, 1/8W, and the magic smoke escaped instantly. The second was 50R, a couple of orders larger in wattage, and much much bigger, and made of metal. After we’d been running the spark table for a while, there was a wisp of smoke from the table, which was starting to melt. So we found four of those in an array, and we wired them up to give us 50R, and they get uncomfortably hot to touch. They’re mounted on an aluminium plate.
Today, Mat converted a lump of car radiator into a heat sink, drilling and tapping all the holes necessary to fit five waaaay chunkier 10R resistors on so we can wire them up with crocodile clips. If we need to water cool them, we can borrow some resistors from someone I know who worked in sound. If /that/ fails, he was telling me about spikes and power switching, and that’s a spare thought. However, this array ought give us a good range from 2-50R, depending on how we wire them, and if 2 Ohms doesn’t set fire to anything, we’re likely to stick with that.
Today, I helped by making tea and not getting in the way, and as a san-check on the positioning of the drill holes, and I also learned a bit about clamping. Mat helped by doing all of the work, and not fucking it up, and also by making tea.
Sparky in Action
Here is Sparky, in all his pint-sized glory:
We’re going to make him spark much harder, and we’re going to clean the water much better, but he’s converted over to an Arduino, and he’s working again.
Sparky v2 – latest code
The code for Sparky Version 2 is just about finished. I need to swap something I did back-to-front with something Mat did far more elegantly and in fewer lines, but the logic’s sound. Here, with a bit of editing, is Oxygen v7. V1-5 were debugging programs of various sorts.
/* Version 7 of Oxygen is the software implementation. * * We do not use pins 0 & 1 (RX/TX) for the main board. * We scan LVL after smoothing, compare to the set voltages of 'max_trigger', and 'min_trigger' trigger DIR to 1 or 0 if we want to move. * We then hit STEP. * Pins should be set to cross directly to DIR and STEP, on veroboard. * For convenience, we begin crossing at pin 3, with pin 2 being the zoom toggle * * For debugging, we output LVL, MAX, MIN, DIR to serial, and comment that out. * * Arduino takes in LVL and four cut-out or direction override pins, plus one 'zoom' pin to speed up or slow down stepping in software, and outputs 7 pins - M0, 1, 2, Step, Dir, /Sleep, /Reset */ // hardware constants for board input/output const int ledPin = 13; const int zoomPin = 2; // earth to 0v on Arduino board to increase speed (decrease software delay) // digital (output) pins (Arduino Pro Mini matched to DRV8825 Stepper Driver) const int dirPin = 3; const int stepPin = 4; const int sleepPin = 5; const int resetPin = 6; // step size pin array int mPins[3] = {7, 8, 9}; const int mPinCount = sizeof(mPins)/sizeof(int); int mPinStates[mPinCount] = {}; // char *mPinNames[mPinCount] = {"M0", "M1", "M2"}; // Probably only ever in debugging/humanised printing // Input for cut-outs and manual drive const int upperCutoutPin = 10; const int lowerCutoutPin = 11; const int driveUpPin = 15; // A1 Can be used as digital pin. const int driveDownPin = 16;// A2 can be used as digital pin. // analogue (measurement) pins const int levelPin = A0; // measurement constants /* lvl = 0...1023 (corresponding to 0 to 5v ish) */ const int AnalogReadsPerVolt = 200; //1000 ish corresponds to 5v #define volts // defines volts as a word to ignore by defining it as blank const int max_trigger = 1 volts * AnalogReadsPerVolt; const int min_trigger = .1 volts * AnalogReadsPerVolt; // measurement variables int lvl = 0; // move-related variables and calculations int move_rate = 100; // Used for speeding up/slowing down in software int step_ratio = 1; // Valid options, 1, 2, 4, 8, 16, 32 int step_index = 0; // used to keep track of which result we want int stepsize_results[] = {32, 16, 8, 4, 2, 1}; const int stepsize_count = sizeof(stepsize_results) / sizeof(int); int modePinSettings[stepsize_count] = {5, 4, 3, 2, 1, 0}; // read from High/Low table in docs, M2 first /* Finds index within modePinSettings, to give us a later result */ int find_index(int array[], int count, int value) { int i; for(i=0; i>= 1; } digitalWrite(sleepPin, HIGH); // /SLEEP - high to suppress behaviour // Reset Stepper Board digitalWrite(resetPin, LOW); delay(5); digitalWrite(resetPin, HIGH); // /RESET digitalWrite(ledPin, HIGH); //Serial.print("Initialised with min "); //Serial.println(min_trigger); } void loop() { if(digitalRead(zoomPin) == LOW){ // move rate will appear twice in each loop that moves, once in each loop that does not move move_rate = 50; } else { move_rate = 500;} //Serial.print("zoomPin: "); //Serial.print(digitalRead(zoomPin)); //Serial.print("move_rate: "); //Serial.println(move_rate); if(digitalRead(driveUpPin) == LOW) { //Serial.println("Drive pin: Up."); stepUp(move_rate); } else if(digitalRead(driveDownPin) == LOW) { //Serial.println("Drive pin: Down."); stepDown(move_rate); // Behaviour under thick fingers: shout at clumsy person } else { lvl = analogRead(levelPin); if(lvl < min_trigger) { //Serial.println("Calling stepUp()"); stepUp(move_rate); // //Serial.println("Moving Up."); // debugging line } else if(lvl > max_trigger) { //Serial.println("Calling stepDown()"); stepDown(move_rate); // //Serial.println("Moving Down."); // debugging line } else {//Serial.println("Fallthrough."); } // lvl not triggering either threshold. Try earthing it to be sure it goes up. } }
Sparky v2 – analogue and digital
I’ve soldered up most of the board for Sparky v2, meaning I now know which pins connect where. The Arduino has analogue pins that can also be used for digital input, so although I’m technically out of digital pins, that’s not really a problem. I’ll be testing that theory soon, using a digital read instead of an analogue read, and I’m pretty sure it’ll end up fine. I’ve written the code, soldered most things, but need some small push buttons to test the code entirely, and I don’t want to put on the stepper driver chip before it’s entirely tested.
Sparky V2 – wrong part
I didn’t want a power transistor. I wanted a voltage converter. They looked the same.
I don’t think anything will have been fried. Leastways, not beyond the LED. In my hands those have the life expectancy of a Spinal Tap drummer, so I’m not bothered.
Sparky v2 – electronics layout
The Version 1 main board of Sparky has a circuit diagram which is neatly broken up into bits, so that every bit does one thing, and they can all be chained together to make up a whole circuit. When we had to add things, it was easy to do, because the diagram was already in bits, so we could swap bits in and out. So, I’m going to try that here. I’ll name each bit for the part, and you should be able to walk through from any part to the end result of that particular bit. Later, I’ll break down the individual bits to their actual wiring, inputs, and outputs. Important parts like capacitors are here so I don’t forget them later, and do not indicate I think a bit is finished.
Power (24 v) -> voltage converter -> 12v and 5v
12v -> smoothing capacitor -> Stepper Driver
12v -> Water pumps (filter and probe, or all in one)
Spark Power -> Spark Board* -> Spark Probe*
Spark Board* -> LVL* -> Arduino
Board cut-outs -> Arduino (input pull-ups)
Frame cut-outs (end stops) -> Arduino
5v Power Indicator LED
Arduino -> Stepper Driver
Reset mini button -> Stepper Driver
Stepper Driver -> Stepper*
—
* Solved problem/finished item
—
The spark board sits on a flying lead, and can be put in at any time. The board cut-outs allow us to drive the stepper in the opposite direction to the expected one, by over-riding the rest of the electronics, meaning we can force the probe up or down. The frame cut-outs are safety interlocks, which stop our motor when we are about to go too far, to protect the parts.
So the Arduino will be taking in the LVL pin, and four different cut-outs, and outputting five instruction pins. (Step, Direction, M0, M1, M2). It will also output the Reset pin so we can be sure the stepper driver is following the Arduino and not moving during boot-up, and the sleep pin, so we can control its waking state. The 5V line itself will power the driver itself, so we can’t power it without the LED coming on. I think the main danger to the driver is if we’re running power through the 12v line when we accidentally unplug it, so that might get changed, but for now I’m planning not to power the driver through the Arduino, which might under exceptional circumstances be powered to 5v while the board is off.
—
ETA: I had a quick convo with Mat and hardly made him wince at all, and I’ve reduced the 24 volt stepper/pump power line to 12 volt, and I’m happier than I was about them being on the same supply. He’s happier than he was because I told him I wasn’t in the same city as him. I was lying, but we do that for people we like. I’m told.
Sparky, redesign in software
So, I’ve probably learned everything I can about electronics from this particular TTL build. For example, I now know what TTL stands for, what 5 volts tastes like, and what a pull-up resistor is. Mat knows that explaining things to a non-expert is haaaaard and that left alone I will do crazy things. So we’ve both learned.
The main board of Sparky is a horror of add-ons, re-mapping, remaking and coloured wires. At least the coloured wires are consistent. Orange for one side of the level we want, green for the other. However, I need to replace most of the bits of the main board with the Arduino.
The step-down needs to be done in hardware. I’m not running 40 volts through an Arduino, even to see what happens[0]. The level comparisons can be done at 5 volts, and indeed it’ll be easier to do that then to twiddle analogue knobs. The first thing we’ll be finding out is whether we’re grounded. If the probe is touching the material, we want to move up. (If we can’t move up, for example because we just hit a switch and the material fell over on the probe, we probably want to cut off the spark circuit, but I’m not building relays into this.)
We want to avoid false positives, so we check a smoothed version of LVL. That smoothing is also done in hardware, with a capacitor.
If the probe isn’t touching the material, then we test to see if the smoothed LVL (see, we’re using the function, or at least a value we passed along) is 0. If so, we move down.
If neither of those things is the case, we leave well alone for Tau, where Tau is the period of the spark capacitor charging. Then we loop again.
‘move’ here is a function, which tells the stepper chip DIR, and then hits the STEP pin. I’m guessing we can do that in two lines of code, and the pause between them will be enough, but DIR might take a moment to wake up, and if that happens it can be dealt with.
—
So, the shape of it:
LVL + | +--Check not grounded -- if grounded move up then start loop again. | + Check not high -- if high, move down then start loop again. | + If nothing else, stay where you are for Tau then start loop again.
Things I’ll need:
- LVL measurement – this will expand the timing loop if we end up sampling repeatedly
- comparator function – /U and /D variables, vs LVL. Check that /U and /D are different and in the correct order – if no space between them, abort and complain.
- spark delay calculator/outer timing loop
- movement function
- tea
On the wishlist:
- Serial.print output in various formats
- M0 M1 M2 pins to be isolated with dipswitches. Whatever they are.
- more tea
[0] If I were going to be doing that, I’d use considerably higher voltage.
Sparky – V2 board
I think I just agreed to write all of Sparky in Software.
Fuck.
Sparky – the state of the code 2015-07-24
Sparky is pretty much functional, and needs making into something good. I’ve re-written the Arduino code with what I’ve learned so far in Learn C the Hard Way, and I’ll use the same board as the Arduino’s on to trigger electronically isolated LEDs, meaning I don’t have to have any outputs, so I can use all the pins for measuring.
The code is as generic as I can make it. Other than the LED pin, none of the pins come pre-named, so you can decide what to plug in where and how, and then output it, as long as you have this program and an Arduino programmer.
/* * * Version 6 of Oxygen is an almost complete re-write. * V6 mounts the LEDs on the in pins, allowing for easy reading, without needing output. Physical output can be provided by buffering LEDs to numbered pins. * V6 has a timing loop of one second, followed by a toggle of the LED on reserved Pin 13. * We do not use pins 0 & 1 (RX/TX). * We scan as many lines as we can find pins for, and store them in an array so we can do good things with them. * The output to Serial Monitor has two possible outputs of human-readable including pin names, or binary string. * * TO DO: binary output function for Serial Monitor * TO DO: use millisecond timing from boot-up rather than a set delay to make the timing loop 1 second * TO DO: Import oscillator code from V5, as separate function applicable to any pin * TO DO: Function to map analogue pins to arbitrary voltage levels (default 5v 2 decimal places). * * May^wDoes contain sarcasm. */ // unchanging constants and annoying variables // #include <stdarg.h> - use for more elegant printing later - Mat to show me how. #includes are not generally needed in Arduino - implicit functions are brought in automatically // Blink stuff int ledState = LOW; int ledPin = 13; // Pin Arrays that I will later resent treating this way // digital (measurement) pins int digitalPinNumbers[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Leave out Pin13. const int digitalPinCount = sizeof(digitalPinNumbers)/sizeof(int); // const so we have a non-variable for indexing char *digitalPinNames[digitalPinCount] = {"Pin 2", "Pin 3", "Pin 4", "Pin 5", "Pin 6", "Pin 7", "Pin 8", "Pin 9", "Pin 10", "Pin 11", "Pin 12"}; // also leave out pin 13 int digitalPinStates[digitalPinCount] = {HIGH}; // Currently working with pull-up resistors. To be changed. // analogue (measurement) pins int analoguePinNumbers[] = {A0, A1, A2, A3, A4, A5}; // A4 & A5 are hard to get to thus likely to float const int analoguePinCount = sizeof(analoguePinNumbers)/sizeof(int); char *analoguePinNames[analoguePinCount] = {"Pin A0", "Pin A1", "Pin A2", "Pin A3", "Pin A4", "Pin A5"}; int analoguePinStates[analoguePinCount] = {}; // misplaced functions I will later regret // !!! TO DO - add binary output !!! void HumanPrint(){ Serial.println("Digital Pins"); for(int i = 0; i < digitalPinCount; i++){ digitalPinStates[i] = digitalRead(digitalPinNumbers[i]); Serial.print(digitalPinNames[i]); Serial.print(": "); Serial.println(digitalPinStates[i]); } Serial.println("Analogue Pins"); for(int i = 0; i < analoguePinCount; i++){ analoguePinStates[i] = analogRead(analoguePinNumbers[i]); Serial.print(analoguePinNames[i]); Serial.print(": "); Serial.println(analoguePinStates[i]); } } void setup(){ Serial.begin(9600); for(int i = 0; i < digitalPinCount; i++){ pinMode(digitalPinNumbers[i], INPUT_PULLUP); } for(int i = 0; i < analoguePinCount; i++){ pinMode(analoguePinNumbers[i], INPUT); } pinMode(ledPin, OUTPUT); Serial.println("Initialised."); } //Do this later - Mat to demo //void SerialPrint(char *v0, varargs ...) //{ //} void loop() { HumanPrint(); ledState = !ledState; digitalWrite(ledPin, ledState); delay(1000); }