An ongoing refrain with modern movies is “Why is all of this CG?”– sometimes, it seems like practical effects are simultaneously a dying art, while at the same time modern technology lets them rise to new hights. [Davis Dewitt] proves that second statement with his RC movie star “robot” for an upcoming feature film.
The video takes us through the design process, including what it’s like to work with studio concept artists. As for the robot, it’s controlled by an Arduino Nano, lots of servos, and a COTS airplane R/C controller, all powered by li-po batteries. This is inside an artfully weathered and painted 3D printed body. Apparently weathering is important to make the character look like a well-loved ‘good guy’. (Shiny is evil, who knew?) Hats off to [Davis] for replicating that weathering for an identical ‘stunt double’.
A common ratchet from your garage may work wonders for tightening hard to reach bolts on whatever everyday projects around the house. However, those over at [Chronova Engineering] had a particularly unusual project where a special ratchet mechanism needed to be developed. And developed it was, an absolutely beautiful machining job is done to create a ratcheting actuator for tendon pulling. Yes, this mechanical steampunk-esk ratchet is meant for yanking on the fleshy strings found in all of us.
The unique mechanism is necessary because of the requirement for bidirectional actuation for bio-mechanics research. Tendons are meant to be pulled and released to measure the movement of the fingers or toes. This is then compared with the distance pulled from the actuator. Hopefully, this method of actuation measurement may help doctors and surgeons treat people with impairments, though in this particular case the “patient” is a chicken’s foot.
Blurred for viewing ease
Manufacturing the mechanism itself consisted of a multitude of watch lathe operations and pantographed patterns. A mixture of custom and commercial screws are used in combination with a peg gear, cams, and a high performance servo to complete the complex ratchet. With simple control from an Arduino, the system completes its use case very effectively.
In all the actuator is an incredible piece of machining ability with one of the least expected use cases. The original public listed video chose to not show the chicken foot itself due to fear of the YouTube overlords.
If you wish to see the actuator in proper action check out the uncensored and unlisted video here.
Thanks to [DjBiohazard] on our Discord server tips-line!
You can send data from one Arduino to another, or create a wireless remote-control system using inexpensive long-range 315MHz or 433MHz wireless data units.
Using this tutorial so you can quickly test and use your units, giving you the knowledge to build upon and make your own projects. So let’s get started!
Testing the modules
Our first guide is to simply test that data can be sent and received from one module to another. This is also an ideal setup for testing the radio range of the units in your area.
An external power supply for one Arduino. This can be an AC-DC wall wart, USB power bank, anything to power it without using the PC that has the receiving Arduino connected to it.
You also need to install the VirtualWire Arduino library. To do this:
Download this .zip file into a temporary or your download directory.
Open the Arduino IDE and select Sketch > Include Library > Add .zip Library…
Navigate to the library .zip download and click “Open”:
After a few moments the library will be installed. You can check that this has completed by selecting Sketch > Include Library> then scroll down the long pop-up menu until you see “VirtualWire” as shown below:
Now – back to the hardware. Allocate one Arduino to be the transmitter, and one the receiver. Upload the following sketch to the transmitter board:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… and upload the following sketch to the receiver board:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Wiring the modules is very easy, they are labelled well and drop straight into a solderless breadboard:
Now connect the transmitter module to your transmitter Arduino as such:
Arduino GND to transmitter GND
Arduino 5V to transmitter Vcc
Arduino digital pin 12 to transmitter SIG:
Next, connect the receiver module to your transmitter Arduino as such:
Arduino GND to receiver GND
Arduino 5V to receiver Vcc
Arduino digital pin 11 to receiver SIG
LED and resistor in series between Arduino digital pin 2 and GND
Now that you’ve assembled both circuits, and uploaded the transmitter and receiver sketches to each board – it’s time to test.
Connect the transmitter board to power, and connect the receiver board to the PC. If not already open, run the Arduino IDE and open the serial monitor. You should notice two things:
The LED on your receiver circuit should blink around once per second. When the LED blinks, this indicates the receiver circuit has successfully received a complete message from the transmitter
The data sent from the transmitter is displayed in the serial monitor.
You can see this in action through the following video:
Our camera had trouble capturing the LED blink in some moments, but that’s ok.
You can also use this two Arduino setup to test the radio range – simply power the transmitter, and power the receiver circuit with a portable source of energy, such as a USB power bank – then walk away from the transmitter. The LED will stop blinking when you’re out of radio range.
You can increase the radio range by increasing the voltage to the transmitter unit – up to 12V DC.
Wireless Remote Control
Now to do something useful – create a wireless digital output control. Our transmitter will have two buttons, and our receiver will control two LEDs via digital outputs. Naturally this is an example, you can use this as a base to control other devices if required.
An external power supply for one Arduino. This can be an AC-DC wall wart, USB power bank, anything to power it without using the PC that has the receiving Arduino connected to it.
We will use two tactile buttons and 10k Ohm pull-down resistors for input. If you’re not familiar with digital inputs and buttons, the building block for this is shown below.
The example diagram uses D12 as the input pin, however for this project your transmitter circuit will need two button circuits, using D8 and D7:
To save time we will use button breakout boards which combine the circuit into a neat unit ideal for prototyping:
Your receiver circuit is the same as the test circuit at the start of this tutorial, except that anothe LED circuit is added to digital pin 3.
Now for the sketches. Upload the following sketch to the transmitter (buttons) Arduino…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… and upload the following sketch to the receiver (LEDs) Arduino:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
You can see a quick demonstration in the following video:
So how did that work?
Review the transmitter sketch. A character is sent over the wireless link which determines the latest operation of the buttons – a, b, c or d (button one high/low, button two high/low).
Review the receiver sketch – on line 19 the switch-case function interrogates the incoming character from the wireless link and determines the action – in this case, controlling the digital outputs which have the two LEDs.
The response speed may seem a little slow – this will be affected by the data speed (300 bps). You can experiment with data speed and radio range (and voltage to the transmitter unit)
You can then alter this for your own means. You may not want to continuously send data as our example does, depending on your needs. As always, have fun and experiment.
Sending data wirelessly from one Arduino to another
Now we’ll show how to send some data in the form of an integer over our wireless link. This is ideal for sending the values of analog inputs, or other data that can be represented as an integer.
The hardware is the same as before – one Arduino transmitting and one Arduino receiving – with the receiver unit connected to a PC so we can use the Serial Monitor to display the received data.
Upload the following sketch to the transmitter Arduino…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… and the following sketch to the receiver Arduino.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Once operating and in radio range, the onboard LEDs will indicate successful transmission and reception of data. Open the serial monitor, and after a moment you will be presented with the data from analogue pin 1 of the transmitter Arduino – for example:
So how did that work?
Review the trasmitter sketch. We took a value from analog pin 1, and stored it into an integer variable on line 25. The VirtualWire library is geared to send data as characters so we convert the integer to a character array on line 28 – which is then sent as usual as shown in line 31.
Now review the receiver sketch. Nothing unusual, and the data from the receiver (in character form) is fed into the array at line 35. Once completed, we add “\0” to the end of the array to signify the end of the data.
The array is then converted back to an integer on line 42, then sent to the Serial Monitor.
So there you have it, we’ve sent integers across the airwaves. You can use your own “codes” with integers to mean all sorts of things and send them across. Ideal for temperature sensors, or anything really.
I hope you had fun experimenting with wireless units, or at least enjoyed reading about the possibilities. To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on x – @tronixstuff.
[Charmed Labs] are responsible for bringing numerous open-source hardware products to fruition over the years, and their latest device is an adorably small robotic camera platform called Goby, currently crowdfunding for its initial release. Goby has a few really clever design features and delivers a capable (and hackable) platform for under 100 USD.
Goby embraces its small size, delivering what its creators dub “tinypresence” — or the feeling of being there, but on a very small scale. Cardboard courses, LEGO arenas, or even tabletop gaming scenery hits different when experienced from a first-person perspective. Goby is entirely reprogrammable with nothing more than a USB cable and the Arduino IDE, while costing less than most Arduino starter kits.
Recharging happens by driving over the charger, then pivoting down so the connectors (the little blunt vampire fangs under and to each side of the camera) come into contact with the charger.
One of the physical features we really like is the tail-like articulated caster at the rear. Flexing this pivots Goby up or down (and can even flip Goby completely over), allowing one to pan and tilt the view without needing to mount the camera on a gimbal. It also comes into play for recharging; Goby simply moves over the disc-shaped charger and pivots down to make contact.
At Goby‘s heart is an ESP32-S3 and OmniVision OV2640 camera sensor streaming a live video feed (and driving controls) with WebRTC. Fitting the WebRTC stack onto an ESP32 wasn’t easy, but opens up possibilities beyond just media streaming.
Goby is set up to make launching an encrypted connection as easy as sharing a URL or scanning a QR code. The link is negotiated between bot and client with the initial help of an external server, and once a peer-to-peer connection is established, the server’s job is done and it is out of the picture. [Charmed Labs]’s code for this functionality — named BitBang — is in beta and destined for an open release as well. While BitBang is being used here to make it effortless to access Goby remotely, it’s more broadly intended to make web access for any ESP32-based device easier to implement.
As far as tiny remote camera platforms go, it might not be as small as rebuilding a Hot Wheels car into a micro RC platform, but it’s definitely more accessible and probably cheaper, to boot. Check it out at the Kickstarter (see the first link in this post) and watch it in action in the video, embedded just below the page break.
The goal of this project is to make a pair of traffic lights that can be used for learning about Arduino digital inputs and outputs – or as the prototype for your own traffic lights in model layouts such as trains, dioramas, LEGO and so on.
Imagine a two-way road that has a single-lane bridge – cars can only travel in one direction at a time. You need to build a system to stop drivers being impatient and risking their lives by approaching the bridge from both sides at the same time.
Your solution is a set of traffic lights. One set at each end of the bridge – east and west, and a sensor to detect cars approaching the lights. We’ll use our traffic light and button modules to keep things simple:
When a car approaches one side – and the lights are red, the car must wait until the light changes. The sensor detects the car and the system changes the lights at the other end from green to yellow to red.
Then the lights at the other side hold red and flash yellow, to give the awaiting motorists a little notice before crossing the bridge – which they can do when the lights change to green. And vice-versa! So let’s get started.
We use the tactile button boards as they are the equivalent to a button circuit with a 10k pull-down resistor; and we use the traffic lights as they are the equivalent of three LEDs with current-limiting resistors… that are much more convenient.
Putting it all together
Thanks to the modules we’re using, the whole system is plug-and-play. The following image is our example in action. But don’t panic – we’ll go through it step-by-step.
First we’ll connect the traffic lights. When you look at the bottom, you can see the pinout labels as such:
We’ll call this the east side. Plug the traffic light module into a solderless breadboard, with the pins across the numerical columns as shown in the final image. Then connect four jumper wires from the solderless breadboard columns matching R Y G GND to the Arduino’s D11, D10, D9 and GND respectively.
Repeat this with another solderless breadboard (we’ll call it the west side) – connect four more jumper wires from the solderless breadboard columns matching R Y G GND to the Arduino’s D4, D3, D2 and GND respectively.
Now for the buttons. They have three pins – 5V, OUT and GND. When the button is pressed, the OUT pin goes from LOW to HIGH:
First, run a jumper wire from the 5V on the Arduino to a blank column on one solderless breadboard. Then run another wire from that column over to the the other solderless breadboard. This gives you 5V on both breadboards.
Next, on each breadboard, run a jumper wire from the traffic lights’ GND pin column to a column next to your 5V column on the breadboard. This gives you 5V and GND on each breadboard.
To connect the west button – connect 5V and GND to the new spots on the solderless breadboard, and the OUT pin to Arduino D5.
And for the east button – connect 5V and GND to the new spots on the solderless breadboard, and the OUT pin to Arduino D12.
Now go back and double-check your wiring – once you’re satisfied it’s time to upload the sketch.
The Arduino sketch
Time for the brains of the operation. Copy the sketch below and upload to your Arduino:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
You can now operate your traffic lights! If you are facing the red light, press the matching button and wait until the lights change before you can cross the bridge.
You can adjust the delays, the speed of light-changing and the other aspects in the sketch. In some countries you may not have flashing yellow before green – so you could remove that feature.
You can see our example in operation from the video below:
Where to from here?
You can now understand how the basic inputs and outputs of an Arduino development board can be harnessed for fun and useful projects. You could expand on this system by adding more traffic lights and buttons – use an Arduino Mega-compatible board as it has plenty more inputs and outputs.
Or you could experiment by using different types of sensors instead of buttons – such as motion detectors, beam-break switches or something home-made.
I hope you had fun with the traffic lights, or at least enjoyed reading about the blinking fun. To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on x – @tronixstuff.
Spectroscopy seems simple: split a beam of light into its constituent wavelengths with a prism or diffraction grating, and measure the intensity of each wavelength. The devil is in the details, though, and what looks simple is often much harder to pull of in practice. You’ll find lots of details in [Gary Boyd]’s write-up of his optical scanning spectrometer project, but no devils.
Schematic diagram of [Gary Boyd]’s Czerny-Turner type scanning spectrometer.A scanning spectrometer is opposed to the more usual camera-type spectrometer we see on these pages in that it uses a single-pixel sensor that sweeps across the spectrum, rather than spreading the spectrum across an imaging sensor.
Specifically, [Gary] has implemented a Czerny-Turner type spectrometer, which is a two-mirror design. The first concave mirror collimates the light coming into the spectrometer from its entrance slit, focusing it on a reflective diffraction grating. The second concave mirror focuses the various rays of light split by the diffraction grating onto the detector.
In this case [Gary] uses a cheap VEML 7700 ambient light sensor mounted to a small linear stage from amazon to achieve a very respectable 1 nm resolution in the range from 360 nm to 980 nm. That’s better than the human eye, so nothing to sneeze at — but [Gary] includes some ideas in his blog post to extend that even further. The whole device is controlled via an Arduino Uno that streams data to [Gary]’s PC.
[Gary] documents everything very well, from his optical mounts to the Arduino code used to drive the stepper motor and take measurements from the VEML 7700 sensor. The LED and laser “turrets” used in calibration are great designs as well. He also shares the spectra this device is capable of capturing– everything from the blackbody of a tungsten lamp used in calibration, to a cuvette of tea, to the sun itself as you can see here. If you have a couple minutes, [Gary]’s full writeup is absolutely worth a read.
Now and again you may find yourself needing to use more than one device with the same I2C bus address with your Arduino.
Such as four OLEDs for a large display – or seven temperature sensors that are wired across a chicken hatchling coop.
These types of problems can be solved with the TCA9548A 1-to-8 I2C Multiplexer Breakout, and in this guide we’ll run through the how to make it happen with some example devices.
Getting Started
First, consider the TCA9548A itself. It is the gateway between your Arduino and eight separate I2C buses. You have a single bus on one side, connected to your Arduino.
On the other side of the TCA9548A, you have eight I2C buses, and only one of these can be connected to the Arduino at a time. For example (from the data sheet):
The TCA9548 can operate on voltages between 1.8 and 5V DC… and operate with devices that have operating voltages between 1.8 and 5V DC. This is very convenient, as (for example) you can use devices made for 3.3V operation with 5V Arduinos, or vice versa. Awesome. So let’s get started.
The breakout board includes inline header pins, which are not soldered to the board. So you need to do that. An easy way to line up the pins properly is to drop them into a solderless breadboard, as such:
Then after a moment or two of soldering, you’re ready to use:
Next, insert your module into a solderless breadboard and wire it up as shown:
We are using the red and blue vertical strips on the breadboard as 5V and GND respectively. Finally, we connect the 5V and GND from the Arduino to the solderless breadboard, and A4/A5 to SDA/SCL respectively on the breakout board:
The electrical connections are as follows (Module — Arduino):
Vin to 5V
GND to GND
A0 to GND
A1 to GND
A2 to GND
SDA to A4
SCL to A5
Next, we consider the I2C bus address for the TCA9548A. Using the wiring setup shown above, the address is set to 0x70. You only need to change this if one of your other devices also has an address of 0x70, as shown in the next step.
Changing the I2C address of the TCA9548A
The bus address of the TCA9548A is changed using the connections to the A0, A1 and A2 pins. By default in the tutorial we use 0x70, by wiring A0~A2 to GND (known as LOW). Using the table below, you can reconfigure to an address between 0x70 and 0x77 by matching the inputs to HIGH (5V) or LOW (GND):
Testing
Before we get too excited, now is a good time to test our wiring to ensure the Arduino can communicate with the TCA9548A. We’ll do this by running an I2C scanner sketch, which returns the bus address of a connected device.
Copy and paste this sketch into your Arduino IDE and upload it to your board.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then, open the serial monitor and set the data rate to 115200. You should be presented with something like the following:
As you can see, our scanner returned an address of 0x70, which matches the wiring described in the bus address table mentioned earlier. If you did not find success, unplug the Arduino from the computer and double-check your wiring – then try again.
Controlling the bus selector
Using the TCA9548A is your sketch is not complex at all, it only requires one step before using your I2C device as normal. That extra step is to instruct the TCA9548A to use one of the eight buses that it controls.
To do this, we send a byte of data to the TCA9548A’s bus register which represents which of the eight buses we want to use. Each bit of the byte is used to turn the bus on or off, with the MSB (most significant bit) for bus 7, and the LSB (least significant bit) for bus 0.
For example, if you sent:
0b00000001 (in binary) or 0 in decimal
… this would activate bus zero.
Or if you sent:
0b00010000 (in binary)
… this would activate bus five.
Once you select a bus, the TCA9548A channels all data in and out of the bus to the Arduino on the selected bus. You only need to send the bus selection data when you want to change buses. We’ll demonstrate that later.
So to make life easier, we can use a little function to easily select the required bus:
void TCA9548A(uint8_t bus)
{
Wire.beginTransmission(0x70); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
}
This function accepts a bus number and places a “1” in the TCA9548A’s bus register matching our requirements. Then, you simply slip this function right before needing to access a device on a particular I2C bus. For example, a device on bus 0:
TCA9548A(0);
… or a device on bus 6:
TCA9548A(6);
A quick note about pull-up resistors
You still need to use pull-up resistors on the eight I2C buses eminating from the TCA9548A. If you’re using an assembled module, such as our example devices – they will have the resistors – so don’t panic.
If not, check the data sheets for your devices to determine the appropriate pull-up resistors value. If this information isn’t available, try 10k0 resistors.
It is has four connections, which are wired as follows (OLED — TCA9548A/Arduino):
GND to GND
Vcc to Arduino 3.3V
CL to TCA9548A SC0 (bus #0, clock pin)
DA to TCA9548A SD1 (bus #0, data pin)
The OLED runs from 3.3V, so that’s why we’re powering it directly from the Arduino’s 3.3V pin.
Now, copy and upload this sketch to your Arduino:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
After a moment the OLED will display some numbers counting down in various amounts (video):
So how did that work? We inserted our bus selection function at line 5 of the sketch, then called the function in at line 22 to tell the TCA9548A that we wanted to use I2C bus zero. Then the rest of the sketch used the OLED as normal.
Controlling two devices
Let’s add another device, a BMP180 barometric pressure sensor module. We’ll connect this to I2C bus number seven on the TCA5948A. There are four connections, which are wired as follows (BMP180 — TCA9548A/Arduino):
GND to GND
Vcc to Arduino 3.3V
CL to TCA9548A SC0 (bus #7, clock pin)
DA to TCA9548A SD1 (bus #7, data pin)
Now, copy and upload this sketch to the Arduino, and after a moment the OLED will display the ambient temperature from the BMP180 in whole degrees Celsius.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is demonstrated in the following video (finger is placed on the BMP180 for force a rise in temperature)(video):
So how did that work? We set up the libraries and required code for the OLED, BMP180 and TCA5948A as usual.
We need to intialise the BMP180, so this is done at line 24 – where we select the I2C bus 7 before initiating the BMP180.
The the sketch operates. On line 34 we again request I2C bus 7 from the TCA9548A, then get the temperature from the BMP180.
On line 38 we request I2C bus 0 from the TCA9548A, and then display the temperature on the OLED. Then repeat.
A quick note about the reset pin
More advanced users will be happy to know they can reset the TCA9548A status, to recover from a bus-fault condition. To do this, simply drop the RESET pin LOW (that is, connect it to GND).
Where to from here?
You can now understand through our worked example how easy it is to use the TCA9548A and access eight secondary I2C buses through the one bus from your Arduino. Don’t forget that the TCA9548A also does double-duty as a level converter, thereby increasing its value to you.
I hope you enjoyed reading about these useful TCA9548A boards. To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on x – @tronixstuff.
In this article we examine a five digit, seven-segment LED display from Hewlett-Packard, the 5082-7415:
We realise they’re most likely now pure unobtanium, but we like some old display p0rn so here you go.
2025 update – Tronixlabs in Australia has a limited quantity of new, old-stock four-digit QDSP6064 displays. Email john at tronixlabs dot com for more information.
According to the data sheet (HP 5082-series.pdf) and other research this was available for a period of time around 1976 and used with other 5082-series modules in other HP products. Such as the Hewlett-Packard 3x series of calculators, for example:
Using the display is very easy – kudos to the engineers at HP for making a simple design that could be reusable in many applications. The 5082-7415 is a common-cathode unit and wiring is very simple – there are the usual eight anodes for segments a~f and the decimal point, and the five cathodes.
As this module isn’t too easily replaceable, I was very conservative with the power supply – feeding just under 1.6V at 10mA to each of the anode pins. A quick test proved very promising:
Excellent – it worked! But now to get it displaying some sort of interesting way. Using the following hardware…
Don’t forget to use the data sheet (HP 5082-series.pdf). You don’t have to use Arduino – any microcontroller with the appropriate I/O can take care of this.
Here is a simple Arduino sketch that scrolls through the digits with and then without the decimal point:
// Arduino sketch to demonstrate HP 5082-7415 LED Display unit
// John Boxall, April 2012
int clockPin=6;
int latchPin=7;
int dataPin=8;
// array for cathodes - sent to second shift register
byte digits[]={
B10000000,
B01000000,
B00100000,
B00010000,
B00001000,
B11111000}; // use digits[6] to turn all on
// array for anodes (to display 0~0) - sent to first shift register
byte numbers[]={
B11111100,
B01100000,
B11011010,
B11110010,
B01100110,
B10110110,
B10111110,
B11100000,
B11111110,
B11110110};
void setup()
{
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
int i;
for ( i=0 ; i<10; i++ )
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, digits[6]);
shiftOut(dataPin, clockPin, LSBFIRST, numbers[i]);
digitalWrite(latchPin, HIGH);
delay(250);
}
// now repeat with decimal point
for ( i=0 ; i<10; i++ )
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, digits[6]);
shiftOut(dataPin, clockPin, LSBFIRST, numbers[i]+1);
digitalWrite(latchPin, HIGH);
delay(250);
}
}
And the results:
Now for something more useful. Here is a function that sends a single digit to a position on the display with the option of turning the decimal point on or off:
void displayDigit(int value, int posit, boolean decPoint)
// displays integer value at digit position posit with decimal point on/off
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, digits[posit]);
if (decPoint==true)
{
shiftOut(dataPin, clockPin, LSBFIRST, numbers[value]+1);
}
else
{
shiftOut(dataPin, clockPin, LSBFIRST, numbers[value]);
}
digitalWrite(latchPin, HIGH);
}
So if you wanted to display the number three in the fourth digit, with the decimal point – use
displayDigit(3,3,true);
with the following result:
We make use of the displayDigit() function in our next sketch. We introduce a new function:
displayInteger(number,cycles);
It accepts a long integer between zero and 99999 (number) and displays it on the module for cycles times:
// Arduino sketch to demonstrate HP 5082-7415 LED Display unit
// Displays numbers on request
// John Boxall, April 2012
int clockPin=6;
int latchPin=7;
int dataPin=8;
// array for cathodes - sent to second shift register
byte digits[]={
B10000000,
B01000000,
B00100000,
B00010000,
B00001000,
B11111000}; // use digits[6] to turn all on
// array for anodes (to display 0~0) - sent to first shift register
byte numbers[]={
B11111100,
B01100000,
B11011010,
B11110010,
B01100110,
B10110110,
B10111110,
B11100000,
B11111110,
B11110110};
void setup()
{
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
randomSeed(analogRead(0));
}
void clearDisplay()
// turns off all digits
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
digitalWrite(latchPin, HIGH);
}
void displayDigit(int value, int posit, boolean decPoint)
// displays integer value at digit position posit with decimal point on/off
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, digits[posit]);
if (decPoint==true)
{
shiftOut(dataPin, clockPin, LSBFIRST, numbers[value]+1);
}
else
{
shiftOut(dataPin, clockPin, LSBFIRST, numbers[value]);
}
digitalWrite(latchPin, HIGH);
}
void displayInteger(long number,int cycles)
// displays a number 'number' on the HP display.
{
long i,j,k,l,z;
float f;
clearDisplay();
for (z=0; z
void loop()
{
long l2;
l2=random(0,100001);
displayInteger(l2,400);
}
For demonstration purposes the sketch displays random numbers, as shown in the video below:
Update – four-digit versions…
They worked very nicely and can be driven in the same method as the 5082-7415s described earlier. In the following video we have run the same sketches with the new displays:
In this chapter we will introduce and examine the use of Ethernet networking with Arduino over local networks and the greater Internet.
It will be assumed that you have a basic understanding of computer networking, such as the knowledge of how to connect computers to a hub/router with RJ45 cables, what an IP and MAC address is, and so on. Furthermore, here is a good quick rundown about Ethernet.
Furthermore you will need to power the board via the external DC socket – the W5100 IC uses more current than the USB power can supply. A 9V 1.5A plug pack/wall wart will suffice.
Finally it does get hot – so be careful not to touch the W5100 after extended use. In case you’re not sure – this is the W5100 IC:
Once you have your Ethernet-enabled Arduino, and have the external power connected – it’s a good idea to check it all works. Open the Arduino IDE and select File > Examples > Ethernet > Webserver. This loads a simple sketch which will display data gathered from the analogue inputs on a web browser. However don’t upload it yet, it needs a slight modification.
You need to specify the IP address of the Ethernet shield – which is done inside the sketch. This is simple, go to the line:
IPAddress ip(192,168,1, 177);
And alter it to match your own setup. For example, in my home the router’s IP address is 10.1.1.1, the printer is 10.1.1.50 and all PCs are below …50. So I will set my shield IP to 10.1.1.77 by altering the line to:
IPAddress ip(10,1,1,77);
You also have the opportunity to change your MAC address. Each piece of networking equipment has a unique serial number to identify itself over a network, and this is normall hard-programmed into the equipments’ firmware. However with Arduino we can define the MAC address ourselves.
If you are running more than one Ethernet shield on your network, ensure they have different MAC addresses by altering the hexadecimal values in the line:
However if you only have one shield just leave it be. There may be the very, very, statistically rare chance of having a MAC address the same as your existing hardware, so that would be another time to change it.
Once you have made your alterations, save and upload the sketch. Now open a web browser and navigate to the IP address you entered in the sketch, and you should be presented with something similar to the following:
What’s happening? The Arduino has been programmed to offer a simple web page with the values measured by the analogue inputs. You can refresh the browser to get updated values.
At this point – please note that the Ethernet shields use digital pins 10~13, so you can’t use those for anything else. Some Arduino Ethernet shields may also have a microSD card socket, which also uses another digital pin – so check with the documentation to find out which one.
Nevertheless, now that we can see the Ethernet shield is working we can move on to something more useful. Let’s dissect the previous example in a simple way, and see how we can distribute and display more interesting data over the network. For reference, all of the Ethernet-related functions are handled by the Ethernet Arduino library. If you examine the previous sketch we just used, the section that will be of interest is:
for (int analogChannel = 0; analogChannel < 6; analogChannel++)
{
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
Hopefully this section of the sketch should be familiar – remember how we have used serial.print(); in the past when sending data to the serial monitor box? Well now we can do the same thing, but sending data from our Ethernet shield back to a web browser – on other words, a very basic type of web page.
However there is something you may or may not want to learn in order to format the output in a readable format – HTML code. I am not a website developer (!) so will not delve into HTML too much.
However if you wish to serve up nicely formatted web pages with your Arduino and so on, here would be a good start. In the interests of simplicity, the following two functions will be the most useful:
client.print(" is ");
Client.print (); allows us to send text or data back to the web page. It works in the same way as serial.print(), so nothing new there. You can also specify the data type in the same way as with serial.print(). Naturally you can also use it to send data back as well. The other useful line is:
client.println("<br />");
which sends the HTML code back to the web browser telling it to start a new line. The part that actually causes the carriage return/new line is the <br /> which is an HTML code (or “tag”) for a new line. So if you are creating more elaborate web page displays, you can just insert other HTML tags in the client.print(); statement.
If you want to learn more about HTML commands, here’s a good tutorial site. Finally – note that the sketch will only send the data when it has been requested, that is when it has received a request from the web browser.
Accessing your Arduino over the Internet
So far – so good. But what if you want to access your Arduino from outside the local network?
You will need a static IP address – that is, the IP address your internet service provider assigns to your connection needs to stay the same. If you don’t have a static IP, as long as you leave your modem/router permanently swiched on your IP shouldn’t change. However that isn’t an optimal solution.
If your ISP cannot offer you a static IP at all, you can still move forward with the project by using an organisation that offers a Dynamic DNS. These organisations offer you your own static IP host name (e.g. mojo.monkeynuts.com) instead of a number, keep track of your changing IP address and linking it to the new host name. From what I can gather, your modem needs to support (have an in-built client for…) these DDNS services. As an example, two companies are No-IP andDynDNS.com. Please note that I haven’t used those two, they are just offered as examples.
Now, to find your IP address… usually this can be found by logging into your router’s administration page – it is usually 192.168.0.1 but could be different. Check with your supplier or ISP if they supplied the hardware. For this example, if I enter 10.1.1.1 in a web browser, and after entering my modem administration password, the following screen is presented:
What you are looking for is your WAN IP address, as you can see in the image above. To keep the pranksters away, I have blacked out some of my address.
The next thing to do is turn on port-forwarding. This tells the router where to redirect incoming requests from the outside world. When the modem receives such a request, we want to send that request to the port number of our Ethernet shield. Using the:
EthernetServer server(125);
function in our sketch has set the port number to 125. Each modem’s configuration screen will look different, but as an example here is one:
So you can see from the line number one in the image above, the inbound port numbers have been set to 125, and the IP address of the Ethernet shield has been set to 10.1.1.77 – the same as in the sketch.
After saving the settings, we’re all set. The external address of my Ethernet shield will be the WAN:125, so to access the Arduino I will type my WAN address with :125 at the end into the browser of the remote web device, which will contact the lonely Ethernet hardware back home.
Furthermore, you may need to alter your modem’s firewall settings, to allow the port 125 to be “open” to incoming requests. Please check your modem documentation for more information on how to do this.
Now from basically any Internet connected device in the free world, I can enter my WAN and port number into the URL field and receive the results. For example, from a phone when it is connected to the Internet via LTE mobile data:
So at this stage you can now display data on a simple web page created by your Arduino and access it from anywhere with unrestricted Internet access. With your previous Arduino knowledge you can now use data from sensors or other parts of a sketch and display it for retrieval.
Displaying sensor data on a web page
As an example of displaying sensor data on a web page, let’s use an inexpensive and popular temperature and humidity sensor – the DHT22. You will need to install the DHT22 Arduino library which can be found on this page. If this is your first time with the DHT22, experiment with the example sketch that’s included with the library so you understand how it works.
Connect the DHT22 with the data pin to Arduino D2, Vin to the 5V pin and GND to … GND.
Now for our sketch – to display the temperature and humidity on a web page. If you’re not up on HTML you can use online services such as this to generate the code, which you can then modify to use in the sketch.
In the example below, the temperature and humidity data from the DHT22 is served in a simple web page:
#include <SPI.h>
#include <Ethernet.h>
// for DHT22 sensor
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10,1,1,77);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(125);
DHT dht(DHTPIN, DHTTYPE);
void setup()
{
dht.begin();
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop()
{
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == 'n' && currentLineIsBlank)
{
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 30"); // refresh the page automatically every 30 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// get data from DHT22 sensor
float h = dht.readHumidity();
float t = dht.readTemperature();
Serial.println(t);
Serial.println(h);
// from here we can enter our own HTML code to create the web page
client.print("<head><title>Office Weather</title></head><body><h1>Office Temperature</h1><p>Temperature - ");
client.print(t);
client.print(" degrees Celsius</p>");
client.print("<p>Humidity - ");
client.print(h);
client.print(" percent</p>");
client.print("<p><em>Page refreshes every 30 seconds.</em></p></body></html>");
break;
}
if (c == 'n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != 'r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}
It is a modification of the IDE’s webserver example sketch that we used previously – with a few modifications. First, the webpage will automatically refresh every 30 seconds – this parameter is set in the line:
client.println("Refresh: 30"); // refresh the page automatically every 30 sec
… and the custom HTML for our web page starts below the line:
// from here we can enter our own HTML code to create the web page
You can then simply insert the required HTML inside client.print() functions to create the layout you need.
Finally – here’s an example screen shot of the example sketch at work:
You now have the framework to create your own web pages that can display various data processed with your Arduino.
To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.
Learn how to measure smaller voltages with greater accuracy using your Arduino.
In this tutorial we’ll look at how you can measure smaller voltages with greater accuracy using the analogue input pins on your Arduino Uno R1 to R3 (not R4!) or compatible board in conjunction with the AREF pin. However first we’ll do some revision to get you up to speed. Please read this post entirely before working with AREF the first time.
Revision
You may recall from previous Arduino tutorials that we used the analogRead() function to measure the voltage of an electrical current from sensors and so on using one of the analogue input pins. The value returned from analogRead() would be between zero an 1023, with zero representing zero volts and 1023 representing the operating voltage of the Arduino board in use.
And when we say the operating voltage – this is the voltage available to the Arduino afterthe power supply circuitry. For example, if you have a typical Arduino Uno board and run it from the USB socket – sure, there is 5V available to the board from the USB socket on your computer or hub – but the voltage is reduced slightly as the current winds around the circuit to the microcontroller – or the USB source just isn’t up to scratch.
This can easily be demonstrated by connecting an Arduino Uno to USB and putting a multimeter set to measure voltage across the 5V and GND pins. Some boards will return as low as 4.8 V, some higher but still below 5V. So if you’re gunning for accuracy, power your board from an external power supply via the DC socket or Vin pin – such as 9V DC. Then after that goes through the power regulator circuit you’ll have a nice 5V, for example:
This is important as the accuracy of any analogRead() values will be affected by not having a true 5 V. If you don’t have any option, you can use some maths in your sketch to compensate for the drop in voltage. For example, if your voltage is 4.8V – the analogRead() range of 0~1023 will relate to 0~4.8V and not 0~5V. This may sound trivial, however if you’re using a sensor that returns a value as a voltage (e.g. the TMP36 temperature sensor) – the calculated value will be wrong. So in the interests of accuracy, use an external power supply.
Why does analogRead() return a value between 0 and 1023?
This is due to the resolution of the ADC. The resolution (for this article) is the degree to which something can be represented numerically. The higher the resolution, the greater accuracy with which something can be represented. We measure resolution in the terms of the number of bits of resolution.
For example, a 1-bit resolution would only allow two (two to the power of one) values – zero and one. A 2-bit resolution would allow four (two to the power of two) values – zero, one, two and three. If we tried to measure a five volt range with a two-bit resolution, and the measured voltage was four volts, our ADC would return a numerical value of 3 – as four volts falls between 3.75 and 5V. It is easier to imagine this with the following image:
So with our example ADC with 2-bit resolution, it can only represent the voltage with four possible resulting values. If the input voltage falls between 0 and 1.25, the ADC returns numerical 0; if the voltage falls between 1.25 and 2.5, the ADC returns a numerical value of 1. And so on. With our Arduino’s ADC range of 0~1023 – we have 1024 possible values – or 2 to the power of 10. So our Arduinos have an ADC with a 10-bit resolution.
So what is AREF?
To cut a long story short, when your Arduino takes an analogue reading, it compares the voltage measured at the analogue pin being used against what is known as the reference voltage. In normal analogRead use, the reference voltage is the operating voltage of the board. For the more popular Arduino boards such as the Uno, Mega, Duemilanove and Leonardo/Yún boards, the operating voltage of 5V. If you have an Arduino Due board, the operating voltage is 3.3V. If you have something else – check the Arduino product page or ask your board supplier.
So if you have a reference voltage of 5V, each unit returned by analogRead() is valued at 0.00488 V. (This is calculated by dividing 1024 into 5V). What if we want to measure voltages between 0 and 2, or 0 and 4.6? How would the ADC know what is 100% of our voltage range?
And therein lies the reason for the AREF pin. AREF means Analogue REFerence. It allows us to feed the Arduino a reference voltage from an external power supply. For example, if we want to measure voltages with a maximum range of 3.3V, we would feed a nice smooth 3.3V into the AREF pin – perhaps from a voltage regulator IC. Then the each step of the ADC would represent around 3.22 millivolts (divide 1024 into 3.3).
Note that the lowest reference voltage you can have is 1.1V. There are two forms of AREF – internal and external, so let’s check them out.
External AREF
An external AREF is where you supply an external reference voltage to the Arduino board. This can come from a regulated power supply, or if you need 3.3V you can get it from the Arduino’s 3.3V pin. If you are using an external power supply, be sure to connect the GND to the Arduino’s GND pin. Or if you’re using the Arduno’s 3.3V source – just run a jumper from the 3.3V pin to the AREF pin.
To activate the external AREF, use the following in void setup():
analogReference(EXTERNAL); // use AREF for reference voltage
This sets the reference voltage to whatever you have connected to the AREF pin – which of course will have a voltage between 1.1V and the board’s operation voltage.
Very important note – when using an external voltage reference, you must set the analogue reference to EXTERNAL before using analogRead(). This will prevent you from shorting the active internal reference voltage and the AREF pin, which can damage the microcontroller on the board.
If necessary for your application, you can revert back to the board’s operating voltage for AREF (that is – back to normal) with the following:
analogReference(DEFAULT);
Now to demonstrate external AREF at work. Using a 3.3V AREF, the following sketch measures the voltage from A0 and displays the percentage of total AREF and the calculated voltage:
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
int analoginput = 0; // our analog pin
int analogamount = 0; // stores incoming value
float percentage = 0; // used to store our percentage value
float voltage =0; // used to store voltage value
void setup()
{
lcd.begin(16, 2);
analogReference(EXTERNAL); // use AREF for reference voltage
}
void loop()
{
lcd.clear();
analogamount=analogRead(analoginput);
percentage=(analogamount/1024.00)*100;
voltage=analogamount*3.222; // in millivolts
lcd.setCursor(0,0);
lcd.print("% of AREF: ");
lcd.print(percentage,2);
lcd.setCursor(0,1);
lcd.print("A0 (mV): ");
lcd.println(voltage,2);
delay(250);
}
The results of the sketch above are shown in the following video:
Internal AREF
The microcontrollers on our Arduino boards can also generate an internal reference voltage of 1.1V and we can use this for AREF work. Simply use the line:
analogReference(INTERNAL);
For Arduino Mega boards, use:
analogReference(INTERNAL1V1);
in void setup() and you’re off. If you have an Arduino Mega there is also a 2.56V reference voltage available which is activated with:
analogReference(INTERNAL2V56);
Finally – before settling on the results from your AREF pin, always calibrate the readings against a known good multimeter.
Conclusion
The AREF function gives you more flexibility with measuring analogue signals. If you are interested in using specific ADC components, we have tutorials on the ADS1110 16-bit ADC and the NXP PCF 8591 8-bit A/D and D/A IC.
To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on X – @tronixstuff.