Seeing Eye to Eye

via SparkFun: Commerce Blog

Hello there, everyone! This week, we have a handful of new products, starting with the new OpenMV H7 Plus Camera - an upgraded version of the existing H7 with a new image sensor and upgraded processing capabilities. We also have the new TFMini-S LiDAR Module with better short range distancing, and a new string of addressable RGB Fairy Lights.

Don't forget that you can get a free SparkFun Qwiic Pro Micro BoogieBoard with any purchase of $75 or more using promo code "BOOGIEBOARD20" (some restrictions apply).

Now onto our new products!

Powerline couldn't have said it better.

OpenMV Cam H7 Plus

OpenMV Cam H7 Plus


The OpenMV H7 Plus Camera is a small, low power microcontroller board that allows you to easily implement applications using machine vision in the real-world. The Plus variation adds 32 MB of external 32-bit SDRAM and 32 MB of external quad SPI flash. You can program the OpenMV Cam in high level Python scripts (courtesy of the MicroPython Operating System) instead of C/C++ - this makes it easier to deal with the complex outputs of machine vision algorithms and work with high level data structures.

TFMini-S - Micro LiDAR Module

TFMini-S - Micro LiDAR Module


The TFMini-S Micro LiDAR Module is a ToF (Time of Flight) LiDAR sensor capable of measuring the distance to an object as close as 10 centimeters (+/- 6 cm up to 6 m) and as far as 12 meters (+/-1% starting at 6 m)! As with all LiDAR sensors, your effective detection distance will vary depending on lighting conditions and the reflectivity of your target object, but what makes this sensor special is its size.

Fairy Lights - Addressable RGB (5m)

Fairy Lights - Addressable RGB (5m)


These addressable RGB LED string lights are a great way to light up any project with no soldering required. The insulated strings come in 5 m lengths with one RGB LED every 5 cm, for a total of 100 LEDs.

That's it for this week! As always, we can't wait to see what you make! Shoot us a tweet @sparkfun, or let us know on Instagram or Facebook. We’d love to see what projects you’ve made!

Never miss a new product!

comments | comment feed

Processing raw image files from a Raspberry Pi High Quality Camera

via Raspberry Pi

When taking photos, most of us simply like to press the shutter button on our cameras and phones so that viewable image is produced almost instantaneously, usually encoded in the well-known JPEG format. However, there are some applications where a little more control over the production of that JPEG is desirable. For instance, you may want more or less de-noising, or you may feel that the colours are not being rendered quite right.

This is where raw (sometimes RAW) files come in. A raw image in this context is a direct capture of the pixels output from the image sensor, with no additional processing. Normally this is in a relatively standard format known as a Bayer image, named after Bryce Bayer who pioneered the technique back in 1974 while working for Kodak. The idea is not to let the on-board hardware ISP (Image Signal Processor) turn the raw Bayer image into a viewable picture, but instead to do it offline with an additional piece of software, often referred to as a raw converter.

A Bayer image records only one colour at each pixel location, in the pattern shown

The raw image is sometimes likened to the old photographic negative, and whilst many camera vendors use their own proprietary formats, the most portable form of raw file is the Digital Negative (or DNG) format, defined by Adobe in 2004. The question at hand is how to obtain DNG files from Raspberry Pi, in such a way that we can process them using our favourite raw converters.

Obtaining a raw image from Raspberry Pi

Many readers will be familiar with the raspistill application, which captures JPEG images from the attached camera. raspistill includes the -r option, which appends all the raw image data to the end of the JPEG file. JPEG viewers will still display the file as normal but ignore the (many megabytes of) raw data tacked on the end. Such a “JPEG+RAW” file can be captured using the terminal command:

raspistill -r -o image.jpg

Unfortunately this JPEG+RAW format is merely what comes out of the camera stack and is not supported by any raw converters. So to make use of it we will have to convert it into a DNG file.


This Python utility converts the Raspberry Pi’s native JPEG+RAW files into DNGs. PyDNG can be installed from, where more complete instructions are available. In brief, we need to perform the following steps:

git clone
cd PyDNG
pip3 install src/.  # note that PyDNG requires Python3

PyDNG can be used as part of larger Python scripts, or it can be run stand-alone. Continuing the raspistill example from before, we can enter in a terminal window:

python3 examples/ image.jpg

The resulting DNG file can be processed by a variety of raw converters. Some are free (such as RawTherapee or dcraw, though the latter is no longer officially developed or supported), and there are many well-known proprietary options (Adobe Camera Raw or Lightroom, for instance). Perhaps users will post in the comments any that they feel have given them good results.

White balancing and colour matrices

Now, one of the bugbears of processing Raspberry Pi raw files up to this point has been the problem of getting sensible colours. Previously, the images have been rendered with a sickly green cast, simply because no colour balancing is being done and green is normally the most sensitive colour channel. In fact it’s even worse than this, as the RGB values in the raw image merely reflect the sensitivity of the sensor’s photo-sites to different wavelengths, and do not a priori have more than a general correlation with the colours as perceived by our own eyes. This is where we need white balancing and colour matrices.

Correct white balance multipliers are required if neutral parts of the scene are to look, well, neutral.  We can use raspistills guesstimate of them, found in the JPEG+RAW file (or you can measure your own on a neutral part of the scene, like a grey card). Matrices and look-up tables are then required to convert colour from ‘camera’ space to the final colour space of choice, mostly sRGB or Adobe RGB.

My thanks go to forum contributors Jack Hogan for measuring these colour matrices, and to Csaba Nagy for implementing them in the PyDNG tool. The results speak for themselves.


Previous attempts at raw conversion are on the left; the results using the updated PyDNG are on the right.

DCP files

For those familiar with DNG files, we include links to DCP (DNG Camera Profile) files (warning: binary format). You can try different ones out in raw converters, and we would encourage users to experiment, to perhaps create their own, and to share their results!

  1. This is a basic colour profile baked into PyDNG, and is the one shown in the results above. It’s sufficiently small that we can view it as a JSON file.
  2. This is an improved (and larger) profile involving look-up tables, and aiming for an overall balanced colour rendition.
  3. This is similar to the previous one, but with some adjustments for skin tones and sky colours.

Note, however, that these files come with a few caveats. Specifically:

  • The calibration is only for a single Raspberry Pi High Quality Camera rather than a known average or “typical” module.
  • The illuminants used for the calibration are merely the ones that we had to hand — the D65 lamp in particular appears to be some way off.
  • The calibration only really works when the colour temperature lies between, or not too far from, the two calibration illuminants, approximately 2900K to 6000K in our case.

So there remains room for improvement. Nevertheless, results across a number of modules have shown these parameters to be a significant step forward.


My thanks again to Jack Hogan for performing the colour matrix calibration with DCamProf, and to Csaba Nagy for adding these new features to PyDNG.

Further reading

  1. There are many resources explaining how a raw (Bayer) image is converted into a viewable RGB or YUV image, among them Jack’s blog post.
  2. To understand the role of the colour matrices in a DNG file, please refer to the DNG specification. Chapter 6 in particular describes how they are used.

The post Processing raw image files from a Raspberry Pi High Quality Camera appeared first on Raspberry Pi.

Chicken coop door automation with Arduino

via Arduino Blog

When Geert Wanten’s wife got tired of opening up the chicken coop to let them out in the morning, he decided to automate the situation using an Arduino Nano.

Wanten’s DIY system calculates the sunup/sundown via info from a DS1307 RTC module, pulling the door up with a gearmotor and a spool of fishing line. When it’s time to drop the door and close things up, the motor is reversed, keeping the chickens safe at night.

Magnetic sensors are implemented to tell the door state, and there’s a manual down switch that releases the door when activated, then goes into normal operation when flipped back.

Code for the project is available in Wanten’s write-up, and you can see it demonstrated in the video below.

Enginursday: Working from Home Just Got a Bit Easier

via SparkFun: Commerce Blog

As working from home transitions from a seemingly temporary precaution into the foreseeable status quo, the difficulties of having to perform all of my job functions remotely become more evident. Out of frustration, I set out to see if I could remedy some of my WFH woes by creating a tool... for tools.

As a member of our QC team, part of my job requires that I construct the testing fixtures I've designed; this almost always necessitates soldering, and often requires the use of rework and diagnostic tools. Fortunately, I have all of these tools available at home, but space constraints prohibit me from having a dedicated workspace where this equipment can remain set up.

Previously I had been setting up all of this equipment on my garage workbench, and disassembling it when finished. Set up and tear down time combined was about 20-30 minutes, but with some planning the impact of that time could be minimized by lumping all of the soldering and rework portions of my projects into one sitting. This seemed to work, but with a rise in cases where I needed to simply swap a resistor or close a jumper, a task that would normally take a few minutes now took upward of 30 if the equipment wasn't already set up - this needed fixing. So just as many schools, shops and labs already do, I decided to fix the problem by employing a cart to house the equipment I needed.

Design Details

The soldering/reworking/testing cart was designed with a four essential functions in mind:

  • First, obviously, the cart must be able to hold and store all the tools I need to solder, rework, and diagnose electrical thingys with.
  • Second, and also obviously, the cart must be able to move the tools needed to the job.

  • Third, it needs to eliminate most of the set up and tear down time that would be needed if the tools were stored while not in use. This means having all the equipment set up and easily accessible.

  • Fourth, the cart itself must not cost more than $40 in raw materials. I already owned all of the tools prior to designing and building the cart, so the cost of the tools is not included in the $40.

alt text

The design ended up being simple, but strong. The cart utilizes two platforms: an upper platform that supports the soldering and rework equipment, and a lower platform that holds supplies and hand-held tools.

The cart needed to be tall enough to be used with a table or desk, but low enough to be usable while, say, working in or under a car. The upper platform's base ended up being 32 inches above the ground. I opted to use 2x4s and ¼” plywood as the structural body and platform floor respectively (as an aside, 2x4’s are certainly overkill, and make the cart a little bulky, but they are also cheap, allowing more money to be spent on casters).

Both platforms are walled with the 2x4’s to prevent items from falling off or out, and three 2x4 sections act as struts between the two platforms. A caster is mounted at each of the four corners of the lower platform, giving it stability and the ability to be rolled and locked in place with ease. Painting the cart ended up being an easy way to clean the whole thing up, as well as making it easier to wipe down.

The main tools that reside on the cart:

  • Hot-air rework and soldering station (combined)
  • Switching DC power supply w/banana-to-gator clips and banana-to-barrel
  • Digital multimeter
  • Amp meter clamp
  • Third arm
  • Wire strippers
  • Tweezers
  • Side cutters
  • Pliers
  • Small ESD mat

NOTE: Mounting a small power strip to the cart meant that only one cord would need to be plugged in in order to power the non-battery powered items.

Has it made anything easier?

It certainly solved my set up and tear down issue. I can be set up and soldering within minutes, and in less than a minute the cart can be back in storage when finished. As a result, my workflow is far less disturbed, and in turn my productivity has risen. As for a non-vocational takeaway, I've procrastinated much less on personal soldering and electrical projects, and it's stimulating thinking of ways to improve the cart's setup.

In reality, there's nothing special about this cart. An equal or better example could be purchased online and delivered to your door in days, but there is something to be said for designing and building your own thing - I certainly found it more rewarding. On that note, next time you have a problem that needs solving, think about taking the time to create your own fix before you buy one - you might be surprised by what you can come up with.

comments | comment feed

Recreate Time Pilot’s free-scrolling action | Wireframe #41

via Raspberry Pi

Fly through the clouds in our re-creation of Konami’s classic 1980s shooter. Mark Vanstone has the code

Arguably one of Konami’s most successful titles, Time Pilot burst into arcades in 1982. Yoshiki Okamoto worked on it secretly, and it proved so successful that a sequel soon followed. In the original, the player flew through five eras, from 1910, 1940, 1970, 1982, and then to the far future: 2001. Aircraft start as biplanes and progress to become UFOs, naturally, by the last level.

Players also rescue other pilots by picking them up as they parachute from their aircraft. The player’s plane stays in the centre of the screen while other game objects move around it. The clouds that give the impression of movement have a parallax style to them, some moving faster than others, offering an illusion of depth.

To make our own version with Pygame Zero, we need eight frames of player aircraft images – one for each direction it can fly. After we create a player Actor object, we can get input from the cursor keys and change the direction the aircraft is pointing with a variable which will be set from zero to 7, zero being the up direction. Before we draw the player to the screen, we set the image of the Actor to the stem image name, plus whatever that direction variable is at the time. That will give us a rotating aircraft.

To provide a sense of movement, we add clouds. We can make a set of random clouds on the screen and move them in the opposite direction to the player aircraft. As we only have eight directions, we can use a lookup table to change the x and y coordinates rather than calculating movement values. When they go off the screen, we can make them reappear on the other side so that we end up with an ‘infinite’ playing area. Add a level variable to the clouds, and we can move them at different speeds on each update() call, producing the parallax effect. Then we need enemies. They will need the same eight frames to move in all directions. For this sample, we will just make one biplane, but more could be made and added.

Our Python homage to Konami’s arcade classic.

To get the enemy plane to fly towards the player, we need a little maths. We use the math.atan2() function to work out the angle between the enemy and the player. We convert that to a direction which we set in the enemy Actor object, and set its image and movement according to that direction variable. We should now have the enemy swooping around the player, but we will also need some bullets. When we create bullets, we need to put them in a list so that we can update each one individually in our update(). When the player hits the fire button, we just need to make a new bullet Actor and append it to the bullets list. We give it a direction (the same as the player Actor) and send it on its way, updating its position in the same way as we have done with the other game objects.

The last thing is to detect bullet hits. We do a quick point collision check and if there’s a match, we create an explosion Actor and respawn the enemy somewhere else. For this sample, we haven’t got any housekeeping code to remove old bullet Actors, which ought to be done if you don’t want the list to get really long, but that’s about all you need: you have yourself a Time Pilot clone!

Here’s Mark’s code for a Time Pilot-style free-scrolling shooter. To get it running on your system, you’ll need to install Pygame Zero. And to download the full code and assets, head here.

Get your copy of Wireframe issue 41

You can read more features like this one in Wireframe issue 41, available directly from Raspberry Pi Press — we deliver worldwide.

And if you’d like a handy digital version of the magazine, you can also download issue 41 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Recreate Time Pilot’s free-scrolling action | Wireframe #41 appeared first on Raspberry Pi.

How I Built a Cap Touch Sound Board with the Qwiic System

via SparkFun: Commerce Blog

Looking for a fun weekend project? You really just need a bunch of Qwiic-enabled breakout boards to tinker with.

The finished Qwiic SoundBoard
The final product

In the Board Assembly department, we're churning them out as fast as our parts suppliers will allow! During my "day job" running the Pick and Place machines at SparkFun, I'm lucky to get to play with our 101+ Qwiic-enabled products every day, hot out of the reflow oven, and I've had this little project in mind for a while. I'd hesitate to call it a "keyboard" in the musical sense, given that the Qwiic MP3 Trigger only plays one track at a time (if you want polyphony, you're looking for the Tsunami Super Wav Trigger).

My Cap Touch Sound Board is exactly what it sounds like - just pop some MP3s on to an SD card and tap the copper pads to play back your noises. The added Qwiic Twist Rotary Encoder allows you to select from up to 84 MP3s (more if you modify the code), changing color depending on which group of 12 tracks is selected for playback.

Cat sniffs color changing Qwiic Twist Rotary Encoder
Thoroughly inspected by Jones the Cat

If you want to build one for yourself, here's the wishlist with all the parts you'll need.

First, I grabbed a piece of the scrap MDF that we have laying around in piles around Board Assembly to use as a panel to mount everything on. If I'm correct, this is the third use this material has seen in its lifetime. We receive these thin fiber board panels as protective packaging in our PCB shipments, but if you look closely at some of the pieces, you can see where they have previously been used as a consumable backing during the PCB milling process (notice the grid of holes on the underside of my project).

A stack of scrap MDF panels
I have a hard time throwing this stuff away, as it's eminently scorable, snappable and hot-glue-able, but I digress.

I got a rough idea of how I wanted everything arranged by simply laying it out on the panel and using a marker to mark where I needed to drill holes for mounting hardware. I also used this template to mark and cut out the holes for the RedBoard Edge (obviously the coolest RedBoard). I decided to mount the battery clip on the front side to take advantage of the barrel jack connector, and also so that all of the most commonly used features would be easily accessible. I did need to drill my own holes on the battery clip since the provided ones don't fit the hardware I'm using.

Arranging the Qwiic Breakout Boards and RedBoard Edge on the Underside of the Panel
Arranging the Qwiic Breakout Boards and RedBoard Edge on the underside of the panel

After settling on this layout, I used a utility knife to score the MDF panel and snapped it to the needed size. Then, I drilled the holes and mounted the electronics. One could connect all of the Qwiic cables first and then mount the electronics to the panel, but I've tried it both ways and mounting first is the way to go. I also drilled holes for some legs to hold the sound board up, which I made out of a couple 2-inch-long, quarter-inch bolts I had laying around. Then it was time to connect all the breakouts with Qwiic cables.

Here are the Qwiic connections:

  • Redboard Edge ----> Main port on Mux Breakout
  • Main port on Mux Breakout ----> Qwiic MP3 Trigger
  • Port 3 on Mux Breakout ----> Qwiic Twist Rotary Encoder
  • Port 4 on Mux Breakout ----> Capacitive Touch Slider #1
  • Port 5 on Mux Breakout ----> Capacitive Touch Slider #2
  • Port 6 on Mux Breakout ----> Capacitive Touch Slider #3
  • Port 7 on Mux Breakout ----> Capacitive Touch Slider #4

And here's what mine looks like:

Electronic hardware mounted with Qwiic cables connected
I made do with the Qwiic cables I had laying around...

You can see in the above Image that I also went ahead and cut twelve strips of copper tape to act as my cap touch pads on the front side of the project. For aesthetic purposes I arranged my pads like piano keys, but one could really do anything with the layout or shape of one's pads. The larger pads wrapped around to the underside of the project, but the smaller ones are floating, so I had to drill some holes next to these and feed jumper wire through to solder to each pad. Finally, after soldering jumper wires to each copper pad, I numbered the pads on the front side of my project and attempted to solder the jumper wires sequentially to the Cap Touch Slider breakout pins.

Here are the results of this attempt: (left pad, middle pad, right pad)

  • Slider #1 ----> Pads 1, 2, 3
  • Slider #2 ----> Pads 4, 5, 6
  • Slider #3 ----> Pads 7, 11, 12
  • Slider #4 ----> Pads 10, 9, 8

Copper cap pads soldered to cap slider breakout pins

I knew I should have used some female headers, but I will just have to sort this out in code. Although it is imperfect, the hardware is now assembled and ready to load up an Arduino sketch. I made this little GitHub repo with the Arduino file and a bunch of sample MP3s to test the system out with.

Here's the sketch:

#include <Wire.h> //Needed for I2C

#include <SparkFun_CAP1203_Registers.h>
#include <SparkFun_CAP1203_Types.h>

#include "SparkFun_Qwiic_MP3_Trigger_Arduino_Library.h" //http://librarymanager/All#SparkFun_MP3_Trigger
#include "SparkFun_Qwiic_Twist_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_Twist

TWIST twist;

CAP1203 sensor010203;  //cap slider connected to mux port 4, keys 1, 2, 3 (left pad, middle pad, right pad)
CAP1203 sensor040506;  //cap slider connected to mux port 5, keys 4, 5, 6 (left pad, middle pad, right pad)
CAP1203 sensor071112;  //cap slider connected to mux port 5, keys 7, 11, 12 (left pad, middle pad, right pad)
CAP1203 sensor100809;  //cap slider connected to mux port 5, keys 10, 9, 8 (left pad, middle pad, right pad)

#define MUX_ADDR 0x70 //7-bit unshifted default I2C Address

//Enables a specific port number
boolean enableMuxPort(byte portNumber)
  if(portNumber > 7) portNumber = 7;

  //Read the current mux settings
  Wire.requestFrom(MUX_ADDR, 1);
  if(!Wire.available()) return(false); //Error
  byte settings =;

  //Set the wanted bit to enable the port
  settings |= (1 << portNumber);



//Disables a specific port number
boolean disableMuxPort(byte portNumber)
  if(portNumber > 7) portNumber = 7;

  //Read the current mux settings
  Wire.requestFrom(MUX_ADDR, 1);
  if(!Wire.available()) return(false); //Error
  byte settings =;

  //Clear the wanted bit to disable the port
  settings &= ~(1 << portNumber);



void setup()


  //Check to see if Qwiic MP3 is present on the bus
  if (mp3.begin() == false)
    Serial.println("Qwiic MP3 failed to respond. Please check wiring and possibly the I2C address.    Freezing...");
    while (1);

  mp3.setVolume(5); //Volume can be 0 (off) to 31 (max)

  enableMuxPort(3); //initialize qwiic twist

  enableMuxPort(4);  //initialize cap touch sensors





void loop()
  int x = 0; //variable used to set track number w/qwiic twist knob


  if (twist.isPressed()){// stop the current playing mp3 when knob pressed

  int twistCount = twist.getCount();

  if(0<= twistCount && twistCount <5){//---------------> red = tracks 1-12
    twist.setColor(255, 0, 0); //red
    x = 0;
  } else if (5<= twistCount && twistCount <10){//------> green = tracks 13-24
    twist.setColor(128, 255, 0); //green
    x = 12;
  } else if (10<= twistCount && twistCount <15){//-----> violet = tracks 25-36
    twist.setColor(128, 0, 255); //violet
    x = 24;
  } else if (15<= twistCount && twistCount <20){//-----> yellow = tracks 37-48
    twist.setColor(255, 255, 0); //yellow
    x = 36;
  } else if (20<= twistCount && twistCount <25){//-----> pink = tracks 49-60
    twist.setColor(128, 0, 255); //pink
    x = 48;
  } else if (25<= twistCount && twistCount <30){//-----> blue = tracks 61-72
    twist.setColor(0, 255, 255); //blue
    x = 60;
  } else if (30<= twistCount && twistCount <35){//-----> orange = tracks 73-84
    twist.setColor(255, 100, 0); //orange
    x = 72;

  if (sensor010203.isLeftTouched() == true) { //----------------> Key 1
    Serial.println("Touch1 left");
  } else if (sensor010203.isMiddleTouched() == true){//---------> Key 1
    Serial.println("Touch1 center");
  } else if (sensor010203.isRightTouched() == true){//----------> Key 3
    Serial.println("Touch1 right");
  //bool reading2 = sensor010203.isTouched();
  if (sensor040506.isLeftTouched() == true) { //----------------> Key 4
    Serial.println("Touch2 left");
  } else if (sensor040506.isMiddleTouched() == true){//---------> Key 5
    Serial.println("Touch2 center");
  } else if (sensor040506.isRightTouched() == true){//----------> Key 6
    Serial.println("Touch2 right");
  //bool reading3 = sensor010203.isTouched();
  if (sensor071112.isLeftTouched() == true) { //----------------> Key 7
    Serial.println("Touch3 left");
  } else if (sensor071112.isMiddleTouched() == true){//---------> Key 12
    Serial.println("Touch3 center");
  } else if (sensor071112.isRightTouched() == true){//----------> Key 11
    Serial.println("Touch3 right");
  //bool reading4 = sensor010203.isTouched();
  if (sensor100809.isLeftTouched() == true) { //----------------> Key 10
    Serial.println("Touch1 left");
  } else if (sensor100809.isMiddleTouched() == true){//---------> Key 9
    Serial.println("Touch1 center");
  } else if (sensor100809.isRightTouched() == true){//----------> Key 8
    Serial.println("Touch1 right");
  delay(0.2);//------------------------------------------------> pseudo debounce

With the MP3s loaded on my SD card, I clicked it in place, hooked up a little hamburger speaker for sound, and hit the power switch. Sometimes I have to hit the reset button to get things going, but once the Qwiic Twist knob is red, the Sound Board should be ready to play the first 12 tracks at the touch of a pad. Pressing the button of the Qwiic Twist will stop any currently playing song. Twisting the knob in either direction changes which songs are played when the pads are touched.

The fully assembled Qwiic Sound Board

If you made it all the way to the end, thanks for reading. If you make this or another cool project using Qwiic enabled parts we'd love to hear about it!

comments | comment feed