Landing : Athabascau University
  • Blogs
  • Getting Started With Circuits, The SparkFun Way

Getting Started With Circuits, The SparkFun Way

Getting Started With Circuits, The SparkFun Way

Getting Started With Circuits

Note: All figures, equations, graphs, YouTube.com links, and most code removed. See pdf for full version: https://goo.gl/PK1a1X .

Contents

Circuit #1: Your First Circuit – Blinking an LED

Circuit #2: Potentiometer

Circuit #3: RGB LED

Circuit #4: Multiple LEDs

Circuit #5: Push Buttons

Circuit #6: Photo Resistor

Circuit #7: Temperature Sensor

Circuit #8: A Single Servo

Circuit #9: Flex Sensor

Circuit #10: Soft Potentiometer

Circuit #11: Piezo Buzzer

Circuit #12: Spinning A Motor

Circuit #13: Relays

Circuit #14: Shift Register

Circuit #15: LCD

Circuit #16: Simon Says

Circuit #1: Your First Circuit – Blinking an LED

Note: This was first written up in Assignment “0” under Writing and executing your first program.

Well, the first circuit in the book is Blinking an LED. All my projects that use a microcontroller have a blinking LED during development. I call it the project’s heartbeat. If that LED quits blinking it means that there is something severely wrong with your code or circuitry, so you’d better quit pretending to write that grant proposal and get out your debugging kit. (There are other, better error indicators, but I still keep this ‘heartbeat’ around. Another way to think of it is a human watchdog: an electronic watchdog makes sure your code keeps running by resetting internal states to known working states, just like you will reset your project to a working state if the blinking LED stops.) Anyway, onwards.

First, energize up the breadboard power rails from the Arduino. Blast, the wires are clipped together – gotta’ get the snips. Alright, snipped, and a black and a red wire chosen to match the breadboard colours. The Arduino pins are all labelled, which is awesome. I’ll use the 5V and GND pins for this rail. Now I need a 330Ω resistor. Man, I can never remember the resistor colour codes, this is going to take forever… Oh, wait a minute, there’s only two values in this kit: 330Ω and 10kΩ – sweet. Resistor plugged in. LED plugged – eh, just a sec – which way? Says flat side to negative. Most LEDs don’t have this handy flat edge, but they do all have a larger anode (-) than cathode (+) inside of the plastic bit, so I’ll go with that. No big deal if it’s backwards at these voltages, as I haven’t seen a non-Zener diode or LED with a reverse breakdown less than 20V. Green wire plugged in.

Hey, it’s blinking, and at the exact opposite rate as the on-board blue LED. Must be related. Yeah, I can see the number “13” printed next to the LED. There must be a resistor between the blue LED and pin 13, too – maybe that tiny one right beside it? Surely there’s some programming involved in this circuit… next page.

Alright, I’ve opened… oh, wait, the examples aren’t showing up. Maybe because I migrated the files while the program was open. Close, restart IDE. Yep, there they are. Okay, circuit example number 1 opened.

Wow, that is tiny text. Must be my high-resolution monitor tricking the IDE into thinking it’s a large monitor. How do I fix that? Can’t see it at all. Let’s ask Google… Alright, this is apparently a common flaw with not only the Arduino IDE but also Swing, a common Java GUI framework, with no official fix. To work around it I must close the IDE and edit preferences.txt. Okay, closed IDE, opened C:\Program Files (x86)\Arduino\lib\preferences.txt with Notepad++ (eh, that needed updating – now updated), and I see this message: # DO NOT MODIFY THIS FILE, OR DELETE SETTINGS FROM THIS FILE. I’m in the wrong preferences.txt. Closed that one, opened ~\AppData\Roaming\Arduino15\preferences.txt, and edited a section to read the following:

editor.font=Monospaced,plain,24
editor.window.height.default=1700
editor.window.height.min=290
editor.window.width.default=3100
editor.window.width.min=400

Looks better now.

Again, example circuit #1 opened. Reading the comments, it looks like we wired it up the opposite way to that in the code commends. The code comments describe wiring the LED and resistor between pin 13 and ground, whereas we wired them between power (+5V) and pin 13. In electronics lingo, we’re using pin 13 as a sink instead of a source. Some microcontrollers, sink and source different amounts of current and require different states to do so, but this one works as is. Still, it’s an oversight.

Hit Sketch > Verify / Compile, and everything went smoothly, then File > Upload. It compiled the program again before uploading. This doesn’t mean I can skip the Verify / Compile step, though, as I’m not sure that it’ll automatically abort the upload if there are compile errors. It doesn’t look like anything changed, but it worked.

Let’s play with the delay values. I’ll make them 100 ms instead of 1000. CTRL+u compiles and uploads. Yep, they’re blinking like crazy now, and I feel guilty like I’ve just been caught speeding. Let’s go with 10 ms. Well, I can’t see it blink any more. My multimeter says that it’s buzzing at 49.95 Hz. Is that right? That’s 20.02 ms – the two 10 ms delays are adding to 20 ms, plus some time to get the switching done, and it probably needs time to do other stuff that we don’t know about yet. I’ll increase those delays to something easier on the eyes before shutting down the IDE, how about 1500 ms and 500 ms.

Circuit #2: Potentiometer

The circuit performed as expected. I could not perceive changes in frequency very well except within a narrow portion of the potentiometer range, and the LED was quite dim when the measured voltage was near zero (at high frequencies). Human perception of changes in frequency is limited in several ways[1]. The result is that we can’t see images changing faster than 15 Hz to 60 Hz, depending on illumination and viewing angles, and we don’t perceive changes in frequencies very well. The SparkFun code varies frequency in a way that makes it difficult for our brain to see the effects. The graph below shows the frequency to voltage relationship of the example code, showing calculated (blue) and measured (orange) values.

I tried to improve this by linearizing the frequency to voltage relationship in the below code.

Circuit_02_straight_line.ino – GitHub.com

[ code removed, see link ]

The above code results in a linear output frequency with respect to voltage, and does not display outside of human perception, as shown in Figure 5.

A more common implementation in the Arduino world uses the map() and constrain() functions, as below.

  freq = constrain(map(freq, 1024, 0, 0, 30),0,30);  // scale frequency with voltage

Circuit #3: RGB LED

I, along with millions of other consumers, have been fascinated by smoothly colour changing smart lights, so watching the RGB LED step through the spectrum was fun.

The SIK guide mentioned, and I did notice it, that the red intensity may appear brighter than the other colours. The SIK guide suggested dividing the target red intensity by 3 to mitigate this (analogWrite(RED_PIN, redIntensity/3);). I went a few steps further and ensured that the total numerical intensity – that is, the intensity value the Arduino uses – always summed to the maximum, changing the relative contributions of each colour without sacrificing overall brightness. Below is the code I used to compare this approach to the original example.

Circuit_03_modified.ino – GitHub.com

[ code removed, see link ]

Normalizing intensities made a little difference, but not as much as I had hoped. There is more going on between supplying current to a certain colour LED and perceiving intensity at a certain wavelength with our brain. First, each colour in the RGB LED does not have the same current to intensity relationship. As the SIK guide mentioned, the red is generally seen as brighter, for example. Also, our eyes do not perceive the visual spectrum equally – we see green best, our acuity generally waning as the spectrum moves towards the infra-red and ultra-violet. Adjusting for just these two factors would be a scientific adventure.

Now that I see the above graph (I did not plug the numbers into Excel until after completing the code), I see that my normalization algorithm is flawed. The normalized sum should always be near 100% of its maximum (1), but I see that it dips to 60% (0.6) in two places and around 85% (0.85) in several. I’ll be sure to check my numbers next time I’m doing calculations.
To test the normalization, I made each colour vary at different sinusoidal rates such that without normalization the cumulative intensity would appear to blink or vary with time, as shown in Figure 10 and Figure 9.

Floats were used (float x, xR, xG, xB, x2sum;) for making the normalization calculations more straight-forward, and the results were then cast to integers (showRGB( int(xR), int(xG), int(xB) );). There are drawbacks to this approach. The Arduino’s ATmega328 does calculations with floats slower than with integers, and accuracy is lost with each calculation and by casting from float to integer. This means that the delay times, hence frequencies, would be different than the same algorithm using integers. I ignored all of this and it seemed to work out just fine. I assume the effect was a reduction in LED switching frequency or increase in delay times, overall.

Circuit #4: Multiple LEDs

This is the type of circuit one can get lost in, playing with the zillion ways one can make lights blink. The term “blinkenlights[2][TL1] has been a silly term among computer geeks since the 1960’s.

The example pattern was inspiration enough for me, so I came up with a series of new ones. The first pattern fades the LEDs on and off, working from one end to the other (firstToLast();); then they all fade on and off (allSlowOnThenOff();); then the ends turn on and fade towards the middle (endsToMiddleThenBack();); and finally, a random scatter of lights (scatter();).

Unfortunately the video clip was corrupted, but I was able to record a screencast of Autodesk’s online Arduino circuit simulator, circuits.io. Note that the Imgur.com GIFV clips were limited to 15 seconds by their video to GIFV converter, so they are separated into the four patterns. (The YouTube.com clip is complete.) The online simulator was great, but it probably took longer to set up the simulation than if I had simply reassembled the circuit using the SIK.

See how it works with the code below.

Circuit_04_modified.ino – GitHub.com

[ code removed, see link ]

Circuit #5: Push Buttons

While the title is ostensibly about buttons, the real value for me in this example was the introduction of logical and comparison operators. Writing code in this short form allows you to see your code in a compact enough form to wrap you brain around it, and, then, to write better code. It is often possible to reduce logical operator trees by examining the corresponding Boolean algebra. The compact way of writing code is like how Boolean algebra is represented, so any insight or experience with one quickly transfers to the other.

The reaction to button presses appears to be instantaneous, though we know it cannot be. Just how quick is it, though? I wanted to know, so I hooked the circuit up to my oscilloscope, shown in Figure 15.

It looks like it takes 40 µs between the button press and LED response, but something looks fishy. There is no “rounding off” of the signals at the transition points (starts, ends), and both the button and LED rise times are identical, at 40 µs. With the 10 kΩ button pull-up resistor, this 40 µs represents an RC capacitance of about 1.5 nF, which is about the capacitance of my probes (in 1X mode). I didn’t notice this at the time, so the measurements are nearly useless. Next time I’ll use the probes in 10X mode, calibrate them beforehand, and, if the measurements still appear to be affected by the probes, consider using my active probes (after figuring out how to calibrate them to the Rigol oscilloscope, as they are usually on an old Tektronix). At least we know that the button to LED response time is no slower than 40 µs.

I made a program that responded to the buttons being pressed for more than a certain amount of time, on top of their original behaviour in the example program. If both buttons are pressed for more than 1 second, then the LED will blink for 1 second. Using timing to extend the functionality of a button means that any button can have several different uses or modes.

Circuit_05_modified.ino – GitHub.com

[ code removed, see link]

Circuit #6: Photo Resistor

Have you ever felt as if street lights turn off in the middle of the night just because you’re near them? Well, first, I suggest digging into this list of cognitive biases. They actually turn on and off based on the time of day, bulb chamber temperature (relevant to the next circuit), and, relevant to this circuit, illumination on a photo resistor.

The idea behind the autotune() function is good, but leaves room for improvement. It would be great if it used an averaging scheme to identify the maximum and minimum levels instead of the extreme measured data points, and even allowed these levels to continuously creep towards the current average. This would take care of spurious values, like ignoring outliers in robust pattern recognition algorithms (Excel straight line, etc.), and allow the system to relatively slowly adapt to new ranges. I did not program these values as I found it difficult to write code with time dependency and fast response time without using interrupts. How are interrupts usually programmed and used in the Arduino world? I’ll have to find out, as this won’t be the last time I run into this difficulty. Below is what I did come up with – no difference from the example code other than formatting it to improve legibility.
The dynamic range of illumination detection was interesting, the circuit and code seeing and calibrating itself to changes in low levels of light, below what I thought it would do. I even had trouble getting the LED to turn off in low light, having to completely cover the sensor with my hands.

Circuit_06_modified.ino – GitHub.com

[ code removed, see link ]

Circuit #7: Temperature Sensor

This example has us reading the temperature sensor values from the serial monitor, as seen in Figure 21. This is great, as we don’t have to wire up extra components to tell us what’s going on under the hood. There is, however, the “blinkenlights” factor – how better to improve any sensor than some panel lighting? The first thing I did after getting the example circuit working was hook a blue, yellow, and red LED up to PWM outputs, seen in Figure 19.

The temperature sensor is the first component in the guide that gave me a bit of grief. The reported temperature wasn’t the same as my calibrated meter. I figured that the sensor had some error, for which could be simply compensated, but none of my linear compensation techniques seemed to do the trick. There was something else going on. Looking at the reported voltages, between 0.67 V and 0.68 V and corresponding to 17.38˚C to 18.36˚C in Figure 21, it looked like the sensor output voltage changed little for a large temperature swing. Looking at the datasheet, I see that it’s 10 mV/˚C, with 2˚C accuracy. The ATmega328 has a 10-bit ADC, which, when using its 5 V source as a reference, means its resolution is about 5 V/210 = 4.9 mV, or about 0.5˚C.

This total error of around 3˚C still wasn’t enough to account for the reported temperature difference, so there was something else going on. This is where we bring in sophisticated electronics fault identification and nullification techniques: I hit the wires a bit and watched the sensor output to see what happened. Something happened – the temperature changed by quite a bit. The most difficult analog electronics faults I have had to deal with always have something to do with grounding problems. (I’m not sure why, but I’m pretty sure it’s a universal law.) In this case, I had the power and ground wires from the RedBoard plugged into the breadboard right next to the LEDs and on the opposite side of the breadboard from the sensor. This means that the relatively power hungry LEDs, each being pulsed with 15 mA at 490 Hz, were tainting the power and ground lines before they could service the sensitive temperature sensor. Moving the RedBoard connections to near the sensor, as in Figure 19, fixed everything like magic. (High speed digital design is indeed magic.)

The last bit or two in general purpose microcontrollers like the ATmega328 will give spurious output in many situations. As calculated above, this means spurious changes up to nearly 2˚C. It would be great to average many inputs to stabilize the reported temperature. As in example circuit #6, though, this is difficult to code without interrupts. While I didn’t use them in my own code, I did later look up how to use interrupts, here: Limitations of delay() & How to Do Timers Correctly, Curie Timer One, FlexiTimer2, and Arduino Time library. Below is the code I ended up with.

Circuit_07_modified.ino – GitHub.com

[ code removed, see link ]

As you can see in the code, I kludged together some linear ramps to control the amount of blue, yellow, and red for a given temperature. The calculations and intended outputs are hinted at in Figure 23. Blue is for 10˚C and below, yellow for about 20˚C, and red for above 40˚C, with proportional mixing in between.

For testing I used an electric barbecue lighter as a heater and a ball of snow as a cooler, and it worked well.

Circuit #8: A Single Servo

We get to move something! This is the bit I’ve been waiting for, what I hope is central to this course. I hooked up the tiny servo as directed, uploaded the example program and watched as it twitched away.

A tip about the screws: make sure you have the right size of screwdriver if attempting to attach one of the servo arms with the included screws, as they are easy to strip. The mounting screws take Phillips #0 and the pivot arm takes what I think is a #2 (my tool isn’t labeled).
There were some power supply issues, as the SIK guide warns against. The LEDs on the RedBoard would pulse and the USB connection would be lost just before the servo twitched, though only during the fastest movements. I connected an external 5 V breadboard supply to the servo and everything was peachy. See it move following the links in Figure 25.

I’m planning on implementing a small robotic arm for this course, the MK2[3] in Figure 27 and Figure 26. It will use 4 servos, one of them, the one that opens and closes the manipulator jaws, the same used in this demo, so I figured that it was as good a time as any to get actuating. I assembled the jaws, hooked up the servo, and plugged it into the Arduino. It just groaned at me and didn’t move. I guess we must deal with physical imperfections, like friction, when trying to actuate in the physical world, huh? I shaved away a bit of the plastic and gave the whole thing a few drops of 3-in-1 oil, then tried the servo again. This time it went through most of the motion range, though it appeared to be complaining and would sometimes get stuck in the extreme “open” position. As the jaws use the servo’s entire 160˚ range, I had to carefully calibrate the end-stops, programming the servo to seek specific positions at which I could attach the gearing, otherwise the jaws would have issues like not closing, closing with too much force, or opening too wide such that the gearing jammed. In the end, it seemed as if the servo was underpowered for its purpose, though it may have been a power supply issue or 3D printing defects and I won’t be looking to replace the servo until after investigating those possibilities.

How much power does a servo need? The datasheet SparkFun provides for this one does not say, and information online is sparse about power or current requirements, only vaguely referring to user experiences needing a power supply of a certain size. The first requirement, which is, I’ve found, the only one usually listed, is voltage. The SIK servo is limited to 4.8 V, and our approximately 5 V supply does not seem to damage it. The next requirement I would consider is average maximum current. How much current can this servo gobble up while doing the most work, averaged over time? I believe this can be measured with a multimeter with “true RMS” capability while stalling the servo arm as it attempts to seek to a position. You’d have to be using a power source that can source more than enough current without sacrificing voltage regulation, like a multi-amp bench supply. The final requirement I’d consider before investing in or designing a supply for a specific servo is peak current. What is the maximum current this servo will ever need? For this I’d use a DSO[4] in “single-shot” mode, though a multimeter with peak detection might work as well. Again, the measurement would be done while stalling the servo arm as it attempts to seek to a position – perhaps use a vice, as many servos have real oomph!

I wanted to see exactly what the PWM signal looked like while driving the loaded servo. The SIK Guide mentions that “a pulse of 1.5 milliseconds will move the servo 90 degrees”, but no more details, so I took a peek, in Figure 29. Pulse widths for the shown range of movement, which was 60˚ to 172˚, was about 1.1 ms to 2.2 ms (5.5% to 11% duty cycle of a 50 Hz signal). I wanted a bit more control over the signal so I attempted to use a function generator (Figure 28) to generate 1-2 ms pulses at 50 Hz. It didn’t work, as my hobby function generator only goes down to about 20% (25%, in specifications), and 1-2 ms of 50 Hz is 5-10% duty, so I gave that up. I later read on Wikipedia.org, however, that, for many servos, changes to the pulse frequency between 40 Hz and 200 Hz do not have an effect, the servo seeing only the “on time” of the pulse. This is different from traditional uses of PWM, in which the duty cycle, that is the ratio of “on time” to “off time” of the signal, determines circuit operation. It also means that one does not necessarily need to control pulse widths: by setting a constant duty, one could simply vary the pulse frequency to control position. For example, with 20% duty, one could vary the pulse frequency between 200 Hz and 100 Hz to generate pulse widths between 1 ms and 2 ms. This is useful in circuit design, as it is sometimes simpler to fix duty cycle than frequency (e.g. requires only a single multivibrator/555-timer). I will be testing this to see what kind of effect the pulse frequency has on the SIK servo.

The example program has us compare the results of issuing commands to seek directly to various positions, and the results of issuing commands to seek gradually, one “step” at a time, to various positions. It certainly had an effect, but the motor still seemed to vibrate as it moved. It wasn’t smooth at all. Wikipedia.org mentions[5] several alternative driving waveforms, where microstepping or half-stepping can be used to make the movement smoother. I’m not sure how one would apply this to our SG90 servo, but the information is available when needed. I’m guessing that one would alternate between various pulse lengths corresponding to “full steps”, to approximate a pulse length in between those given and seek to a step in between the full steps.

In the code I used to cycle the jaws, notice that the command for the extreme ends are repeated or held for a short time, but longer than the seeking delay (20 ms). There are two reasons: to try gripping something with force in the closed position, like a piece of paper; and to ensure the jaws fully opened, as it was in this position that they had the most friction (the most detent torque of the whole system).

Circuit_08_pincher.ino – GitHub.com

[ code removed, see link ]

Circuit #9: Flex Sensor

Now we can wiggle a finger and the robot waggles back. Neat. This flex sensor can be used in many different applications including, as the SIK Guide mentions, the Nintendo Power Glove.

Plugged into a breadboard, however, isn’t the best place for it. The base and connectors are fragile and need support, especially since the sensor is designed for strains that torque at its base. It may be a good idea to use a mechanism, like a case or guides, to constrain its movement so it can’t bend backwards or to the sides, and to avoid pinching it.

The SIK Guide talks about “Debugging your sketches using the Serial Monitor.” While your own debug solution using the serial monitor can be superior to LEDs, actuator outputs, or circuit measurements, it isn’t nearly as good as modern debug protocols. If your code is more complicated than a script or if you can’t figure out why it’s not running as expected, there is nothing better than a modern debugger. I’m not sure how it would work in the Arduino world, but some superficial research reveals several solutions, such as compiling code with the Arduino IDE then uploading it to the chip with a hardware debugger over Atmel’s DebugWIRE protocol[7]. You wouldn’t be debugging the same code typed into the Arduino IDE, though, but the C++ that it generates. (It should be close, though.) Another option is to use the Atmel Studio Simulator in a debugging session[8], by loading the ELF file output from the Arduino IDE. All that said, I will still use a blinking LED as a visual reassurance that my code hasn’t melted down, and the odd Serial.println(yourVariable) to let me know what a certain variable is and which part of my program is executing.
The example circuit has RedBoard reading the flex sensor position and then driving the SIK servo (from Circuit #8: A Single Servo) to an applicable position. My SIK servo had been attached to a gear-driven jaw clamping system, and would not act the same if it were free of the friction and backlash, so I used a different servo: the Power Pro MG 946R. It uses more power than the SG90, so I was sure to hook it up to an external supply[6].

Circuit #10: Soft Potentiometer

This is an improved version of the “contact wiper” circuit element, often found in rotary dials. It worked well, and the RGB LED output was great, seen in the Imgur.com and YouTube.com links under Figure 34. (Maybe I just like sparkly lights.) Right now, we’re using our finger to actuate it, but the datasheet and a peruse of the internet shows that mechanical “fingers” are often used to press the film contact in a repeatable and accurate way.

You’ll notice that I try pressing on two locations at once. It should be possible to detect two pressed locations at the same time, using some math. Pressing in two locations effectively shorts the resistive element between those two locations. (Don’t press the two ends at the same time without a series limiting resistor.) Pressing with a 3-dimensional, physical object on a continuous line will never be a point contact but an area contact. With the Softpot, the effect is essentially a short between the extremes of the contact area along the resistive strip. This can be represented the same way as two point contacts, in Figure 33, and Equation 1, where  is the resistance between terminals a and b, and  is the length of the strip. By powering  and adding grounded limiting resistors to  and  and measuring their voltage, just like we add a 10 kΩ grounded limiting resistor and measure the voltage in the example circuit, and by doing a bit of math, we can figure out the positions of two points. I didn’t implement the proposed two-point detection as it wasn’t needed, but will keep it in mind.

Circuit #11: Piezo Buzzer

Just got Rick rolled again. Been a while. This example circuit is as simple as it gets, but it’s fun to make sounds.

Circuit_11_modified.ino – GitHub.com

The example uses a cumbersome combination of 8 letters (one octave) and tone lengths to create songs. While toying with the possibility of improving this approach I found several ways of representing music (MusicXML, MEI, NIFF, MIDI). (In other words, I found even more cumbersome methods, albeit standardized and accurate.) I certainly didn’t want to write an XML or other file interpreter for this example, but I still wanted to go beyond the single octave and test the speaker’s capability, so I wrote a script that outputs frequencies representing each key on a standard 88-key piano. Piano key frequencies can be calculated with Equation 1 and Equation 2.

Having a square wave (“bit banged”) frequency output by a chain of drivers, compilers, and C++ programming will inevitably generate variations from the exact sinusoidal wave frequency the formula was intended for. I tried measuring some of these errors, the first being type bit length limitations and type conversion errors in Figure 37, the second being driver and hardware (and measurement) limitations in Figure 38. Neither the digital type errors (Figure 37) nor the hardware limitations were significant, even at low frequencies. The type errors could be improved slightly by rounding the number prior to casting it as an integer, or by using a function like tone() that can handle floats. Harmonic distortion, that is the error between our actual output and an ideal sinusoidal tone, could be improved by approaches that attempt to output sinusoids. The piezo buzzer has limitations obvious to those comparing its output to that of a proper speaker and driver circuit, some of which can be compensated for by building a lookup table that translates intended frequency and volume (among other characteristics about which I am unaware, I’m sure) to required input.

Sound can be heard following the links under Figure 36.

Circuit #12: Spinning A Motor

The motor is great, and having introduced transistors opens a world of possibilities. They are decent buffers, amplifiers, logic blocks, and even sensors. The P2N2222AG is a 40 V, 600 mA, 1.5 W bipolar junction transistor (BJT), not like the transistors in most of today’s digital circuits, which are typically field effect transistors (FETs).

Taking great care not to mix up the legs on the transistor, this circuit was hooked up and running as specified. As mentioned in the SIK guide, the motor would not turn at low input voltages. A bit of research indicates that this is due to a whole bunch of things that I’m not happy about jumping into. I noticed that the motor would continue to spin at lower RPM when slowed from higher speeds than when attempting to start from rest, so I wrote a function (void motorGo(int speedGoal)) that kick-starts the motor with full voltage for a short period, just enough time to get it moving, before setting the target speed. These numbers would change with different motors and time, even those of the same type, due to manufacturing differences and wear, and with different driving circuitry (transistor, etc.). It worked well, allowing the speed to be reliably set as low as 35 (of the 255 analog settings), as opposed to a minimum setting of around 60 in the example program. I believe this could be further improved with increased drive voltage, by better tuning a drive signal to the motor characteristics, or by using a feedback circuit that somehow reacts to differences in target RPM and actual motor speed (for example, by measuring and comparing average drive current against target current).

Circuit_12_modified.ino – GitHub.com

[ code removed, see link ]

The video demonstration links in Figure 40 would be more informative as oscilloscope traces, but it shows that a small base voltage change results in a large motor drive voltage change. The linked demos are using the motorGo() function, not the example program.

Circuit #13: Relays

It sounds like I’ve left my car blinker on, now that this circuit is running. “Tick-tock, tick-tock,” it goes, sounding like it uses the exact same relay as the signal relay in automobiles. Relays are robust, simple, and can switch large voltages and power, including AC.

They’re not very quick, though, relative to the digital components we’ve been working on with the SIK and RedBoard. I wanted to find out exactly how quick this relay was, so I took some measurements using a function generator to drive the transistor. A 10 ms delay produced a consistently clean switch, seen in Figure 43. Once down to 5 ms delays as seen in Figure 42, the output was messy, though it still appeared to work for a circuit like an LED. One can clearly see a “bounce” signal of about 50% the “on” voltage after the relay appears to turn off, which could fool a different circuit like a digital reading into thinking that the relay had turned back on. The “bounce” signal amplitude appeared to be related to a harmonic frequency of the relay itself, perhaps due the physics of a magnetic field controlling a metal element with momentum, as at 120 Hz, as in Figure 47, though the “on” signal is further degraded, the bounce is gone. A 5 V drive voltage appears to take about 3 ms for the relay to hit its initial “on” state without considering the quality of the signal. As such, delays around 3 ms should create a harmonic oscillation with the relay armature. The system can be studied as a driven damped harmonic oscillator, where any overshoot results in a “switch”. One effect in such a system is that the oscillation can grow when driven near their resonance frequency, which, in this case, means that the “on” and “off” signals are cleaner than what we’d expect at such a high frequency. This is shown in Figure 48 and Figure 46. At drive frequencies above 167 Hz (3 ms delays, or 6 ms period) and too far from the system’s resonant frequency or its harmonics, the signal is damped to the extant where its position cannot be predicted. Though it stays in the “off” position in Figure 45, I would not trust this example to be the rule, as the armature could end up in any position between “on” and “off”. Also, although I didn’t test frequencies above 560 Hz with any scrutiny (I did spot-test a few in the kHz-range with no change in output), I would not be surprised if this relay could be successfully switched at a higher harmonic of the resonant frequency. The pragmatic takeaway from this experiment isn’t about driving damped harmonic systems, as interesting as it is, but that this relay needs more than 3 ms to switch at all, ideally 10 ms or more for a clean signal.

The switch delay may be improved by increasing the driving voltage, as that would generate a greater magnetic field to move the armature. This relay, a JZC-11F, can handle a coil voltage of up to 12 V.

Circuit #14: Shift Register

 

Shift registers remove a large drawback when designing systems with microcontrollers: limited pin counts. Multiplexers perform a similar task, though in a parallel fashion rather than serial, and may have bi-directional operation. This example gives us a glimpse of how digital communication works at the lowest level, using a minimum number of conductors to transmit vast amounts of information. One can even use a single conductor if they choose an encoding technique that can survive the trip[9].

We also get to play with LEDs, which is fun. This example program provided plenty of demos. Here they are:

Circuit #15: LCD

A screen! LCDs are everywhere, so any experience with them is a boon to any designer or hacker. How many times have you wished you could change the display in your car, or get explicit error messages from the office printer instead of things like “lp0 on fire”? Well, I have, and now, having gone through this exercise (Imgur.com, YouTube.com), I’m better equipped to make it so.

The example program (SIK_Guide_Code_32\Circuit_15.ino)  refers to examples “showing off the features of the LiquidCrystal library”, so I tried them out.

Circuit #16: Simon Says

I hadn’t played an electronic Simon Says game since I was a child, more than 25 years ago (“25 minutes ago!”, claims my girlfriend), and I had forgotten how much fun it can be. I had a bit of trouble getting ahead of myself and wiring the wrong pin to button or LED, and had to redo it, carefully following the coloured diagram. I noticed that the sound pitch was not in a linear order with the buttons. Also, in contrast to playing with the Milton Bradley (Hasbro, nowadays) disc-like version, my mind couldn’t help but think that our line of coloured buttons on a breadboard were positioned incorrectly. The old Simon game must have hard-wired my brain to reject all but the original. Perhaps we are all robots

Looking at the code, I saw that there are three modes: MODE_MEMORY, MODE_BATTLE, and MODE_BEEGEES. It normally runs in MODE_MEMORY, but the user can get into either MODE_BATTLE or MODE_BEEGEES by holding the green or yellow button, respectively. I tried them both out and recorded the tune played by MODE_BEEGEES (YouTube.com, SoundCloud.com). Though the SparkFun programmers did their best to emulate Stayin’ Alive by the Bee Gees, I believe there is room for improvement, and I’m not talking about the music. The tutorial SimpleAudioPlayer shows how to play a WAV file[10] from an SD card on a amplified speaker, which can be modified to fit our piezo buzzer by getting rid of all of the circuitry (a piezo can be driven directly from an Arduino pin), though it won’t sound as good as the speaker.


Endnotes (Footnotes)

[1] Luu, C., and Kalloniatis, M., 2007, Temporal Resolution, Webvision: The Organization of the Retina and Visual System, http://webvision.med.utah.edu/book/part-viii-gabac-receptors/temporal-resolution/ (February 16, 2017)

[2] Raymond, E., 2003, blinkenlights, The Jargon File version 4.4.7, http://www.catb.org/~esr/jargon/html/B/blinkenlights.html (February 17, 2017)

[3] EEZYbotARM MK2 by Carlo Franciscone from EEZYrobots, licensed under CC BY-NC.

[4] Digital Storage Oscilloscope

[5] Wikipedia contributors, "Stepper motor," Wikipedia, The Free Encyclopedia, https://en.wikipedia.org/w/index.php?title=Stepper_motor (accessed February 21, 2017).

[6] It turns out that this was not sufficient, as my power supply failed during experimentation which, somehow, resulted in a cascading failure that fried the RedBoard (ATmega328 and FTDI chip), 10 m active USB cable, and laptop computer (it was okay after a manual battery reset). Lessons learned: protect and isolate your circuits. Pictured supply has proper protection. See link for details: Discussion > COMP 444 > Recommended: Isolate Your USB Connections.

[9] Some codes are made to continuously oscillate, such as all wireless protocols and Manchester encoding.

[10] Stayin’ Alive by the Bee Gees WAV file available here: http://members.tripod.com/~Natalie20/stayin.wav.