Author Archives: Eric Orosel

Enginursday: Efficiency Gains through Design

via SparkFun: Commerce Blog

Efficiency is the name of the game these days, and the SparkFun QC team is all about it! We have successfully deployed a new test-fixture we are calling the “Qwiic Test-bed” and I am here to tell you all about it.

If you are new to SparkFun or haven’t stopped by for a while, you may not be aware of our Qwiic line of products, if so, check out this Qwiic explainer. Being a high variation electronics manufacturer, we in QC keep very busy designing testing hardware and software for new SparkFun originals. We are always trying to find and take advantage of efficiency gains to increase the bandwidth of our three-person team, and the new Qwiic Test-bed does just that. Below is a brief overview of the reasoning, technical details and results of developing with our new test-fixture.

alt text

The Motivation:

We wanted to find a way that we, as a team, could increase our bandwidth by saving time developing. Typically we design a test-bed for a product, and that test-bed is only used to test that individual product. This means for each new product we have to: design new testing hardware, build the new test-fixtures, write the software to control the test-fixture and test the product, and maintain the test-fixture through ongoing Production use.

One of the easiest steps we can take to save time during our hardware design process is to repurpose past design files and make modifications to suit your current application, and the same can be done for testing software. But even with these efficiency gains we can’t outrun the turnaround time on test-fixture hardware. What we needed was a physical test-fixture that could be reused to test new products while still supporting the old.

alt text

The key to making this test-fixture possible was in part due to the standardization in form factor and pinout of the Qwiic breakout boards, and in part due to all of the boards utilizing the I2C communication protocol. One hard standard was set in regards to form-factor, this standard dictates the ordering of the four essential plated through holes (PTHs): ground (GND), power (VCC), I2C data (SDA), and I2C clock (SCL) (they must also be adjacent).

It should be said that this test-bed was never intended to be able to test every Qwiic breakout board, we just want to capture the majority - some designs just need to break the standard for one reason or another, and trying to design a fixture around all the imaginable deviations would have caused too much scope creep.

The point of the exercise was to expedite as much of the development process as possible when using the Qwiic Test-bed. We opted to use a collaborative firmware sketch that runs on the test-bed, allowing us to build on the test-bed firmware by easily adding new product source files and testing functions required to test new designs. This meant that we could now use the same physical test-fixtures to test multiple assemblies, thus saving time on building up hardware for each new design. By removing the need to design and assemble a physical fixture we’ve saved a bunch of our team’s time, and also allowed the product cycle to move quicker. As an added bonus, the fixture can also be used during the prototyping phase to test new hardware and software.

alt text


The Qwiic test-bed utilizes pogopins to make a temporary connection to the board’s PTHs while the board is held in place by the hinged acrylic bar on the top. A small nubbin can be spun to keep the bar clamped on the board during testing, or the user can manually hold the bar down. The processing and testing peripherals for the test-fixture are handled by our original testing development board called the “Flying Jalapeno.” Check out Pete’s posts about the development of the Flying Jalapeno here:

The test-fixture has two available capacitive sensor pads, four LEDs, and available serial debug for the user to interface with.

alt text

The fixture centers around the four main pogopins: GND, VCC, SDA and SCL, which are separated by a standard 100 mil spacing. Because many of these assemblies break out other signals such as interrupts, enables, analogs, PPMs, clocks and serial RX/TX, the four essential signal pogopins are straddled by eight extra pogopins - four above and four below. Five 74LVC4066 quad switches route the most functionally capable pins from the Flying Jalapeno’s ATmega2560 to the eight extra pogopins, giving the developer the ability to select which pins of the 2560 to connect to the test-board’s signals, and which to disconnect.

alt text

Qwiic Test-bed Schematic (PDF LINK)

By making the acrylic mating surface for the PTH connections slim, a test-board can be placed on either side of the mating area to suit any PTH header orientation. Alignment is facilitated by matching the silk of the test-board with that of the test-bed. In most scenarios, the assembly being tested has fewer PTHs than the test-bed has pogopins; when a pogopin is not being used it’s pushed down by the PCB and separated from any signal by the mask. Reports about usage from our Production department have been positive, and the hardware is holding up well.


As a whole we’ve been very pleased with the results of using this test-fixture. The three of us in QC are getting a lesson in software collaboration, but with a few rules implemented, co-development has gone smoothly. As a rough calculation, the testing development process for the boards being tested with the Qwiic Test-bed took about 25 percent of the time they would have previously, and with all the projects in the pipes, saving any amount of time is welcomed.

comments | comment feed

Enginursday: Keycode Security Starter, Part 2

via SparkFun: Commerce Blog

This is part two of a multi-part write up. If you haven’t read part one, check it out before proceeding. Utilmately, the effort is to create a keycode security system for an 80's era car that was not built assembled with one from the factory. The concept is basic – a keypad acts as the HID, and once the correct PIN is entered through the keypad, the microcontroller closes a relay completing the starter solenoid circuit, allowing the operator to start the car in the typical fashion – using a key to rotate the ignition switch thus actuating the starter. Read on for a write up depicting the prototyping phase of the project.

alt text

To give myself the opportunity to test the concept and the hardware in the intended operational environment, I created a fixture to house the hardware. There were a few necessary features the fixture needed to have: the components and wires need to be easily inspectable and accessible, and the fixture needs to be small enough to allow me to move it around the vehicle for testing variation. I opted to laser cut two pieces of 1/4” acrylic that I could affix the hardware to. Conveniently, Autodesk's EAGLE PCB layout editor ships with a built-in DXF file generating ULP. The ULP uses the dimension layer to generate the file, so you would just remove all layers except the dimension layer and run the ULP, and you will be treated to a scaled DXF file of your PCB design.

alt text

This ULP was the key to to producing the acrylic plates (if I didn’t have access to a laser cutter, I would have likely used some thin plywood that I could easily drill and cut apertures into). The acrylic plates sandwich the boards and components, and are held together by a combination of screws and aluminum and plastic standoffs.

alt text

alt text

Only four cables need to be broken out of the fixture. The first two are required to power the microcontroller: a power cable that will connect to a 12V source, and a GND cable that will be connected to a body ground. The other two will span an open in the starter solenoid circuit, and can be connected via the Qwiic Relay or the toggle switch. The 12V source wire is terminated with a female spade connector to allow easy connection to the vehicle's fuse block. The body ground wire is terminated with an alligator clip, making it easy to connect to ground points all over the car. The two wires that span the starter solenoid circuit are terminated with spade connectors as well - one female and one male. Lastly, the microB USB connector of the ESP32 WROOM is accessible through the side of the fixture, allowing easy reprogramming of the micro-controller.

alt text

I opted to use a minimum of 11 AWG cable for spanning the starter solenoid circuit; the conductor diameter in this cable is capable of surviving the amperage needed to hold the starter solenoid in place during the starting operation. As for the power circuit I opted to use a 1A fuse in series with 16 AWG cable for the 12V, and a 20 AWG cable for the body ground connections. The fuse should protect the car in the chance that any of the added components malfunction.

Stay tuned for the next installment where the security starter gets tested in the car.

comments | comment feed

Enginursday: An Old Lamp Learns New Tricks

via SparkFun: Commerce Blog

In the spirit of the three R's, I decided to update an old, broken incandescent lamp with some addressable LEDs and trimpots.

The poor old lamp was on a steady decline, and after the second of the three lamp heads failed to power its bulb, it was clear that the old fixture was on its way to becoming fully dysfunctional. Needing to fix the old lamp presented the opportunity to upgrade its old, power-hungry internals with some more efficient and functionally-rich replacements. I began disassembly to see what we were working with.

alt text


The lamp itself is nothing unique; it has a metal body that can be pretty easily separated into two main parts: the stand and post, and what I'm calling a "collector," with the three necks and lamp head on each. The two can be separated by unscrewing the post from the collector and cutting all cables connecting the two parts. The plan was to gut all of the original circuitry, so it was easiest just to cut any cables that got in the way. Once separated, the cables could be pulled free from the stand.

Each lamp head is connected to its respective neck by a pass-through fixture that acts as a swivel, allowing the cables from the collector/neck to pass through to the head of the lamp. These were easily removed by unscrewing two screws - one acts to clamp the two halves of the swivel to the neck, and the other retains an elbow that carries the lamp head. The same process was followed to separate the two other heads from the necks, allowing the remaining wires to be pulled from the collector and necks.

alt text

The lamp heads proved the most bothersome to disassemble. Within each lamp was the switch and bulb assembly, which was fixed to the elbow portion of the swivel by two washers and a retaining nut. Because of clearance issues, it was more or less impossible to fit a standard-width wrench onto the retaining nut. Luckily I had some skinny wrenches that would work, but it was still a big pain only being able to turn the nut about 40 degrees before having to reset the wrench.

Once this nut was removed, the elbow portion of the swivel could be removed from the lamp head, leaving the switch knob nut at the back of the lamp head as the last piece of hardware. Removing the switch nut allowed the switch and bulb assembly to be pulled from the lamp head, leaving it empty.

Finding some new parts

In an effort to increase efficiency and functionality over the old incandescent setup, I opted to replace the light-emitting components with addressable CRGB LEDs. With many options out there, I set out around the office to see what some of the more experienced addressable LED users would recommend for the application.

I decided to use one of our LuMini LED Rings for each of the lamp heads. The LuMini rings seemed a good fit - the shape of the ring coincides with the shape of the lamp heads, and they have handy mounting points I could use. These LED rings are available in three sizes, with LED count increasing respectively. I opted to use the SparkFun LuMini LED Ring - 1 Inch, which employs 20 APA102 addressable LEDs.

alt text

I set two initial goals for this project: the first was to be able to adjust the brightness of each lamp individually, and the second was to be able to change the color the lamps emit. I decided to add a trimpot to each lamp head that would take the place of the old rotary switch, as well as add one trimpot to the stand of the lamp. The trimpot on each of the heads would adjust the brightness of the corresponding LEDs of that lamp head, and the trimpot in the stand would control the color of all the LEDS. For this job I chose to use four 10K Ohm linear rotary potentiometers. Coinsidently, these trimpots mimic the look and size of the old rotary switches, which proved very handy for installation.

alt text

It was finally time to choose a microcontroller that would both suit the immediate application and not limit the future addition of features. I decided on the SparkFun Thing Plus - ESP32 WROOM as the brain of the lamp, because of its wireless capabilities and the functionality that accompanies them.

alt text

The last item to flush out before assembly was the method for mounting the LED rings to the lamp heads. The previous switch and bulb assembly had a bracket integrated into the assembly, so I needed something similar in width that I could shape to fit the application. After looking around the hardware store, I settled on using some stainless steel lumber framing brackets.

alt text

What’s nice about these brackets is that they were pre-drilled with apertures that would suit the application: a large hole that would fit over the threads of the hinge, and a smaller hole that could be used to attach 4-40 standoffs to mount the LED ring. The stainless brackets are also thin enough to easily cut with tin snips and bend with pliers. At this point it was time to begin assembly.


I started by measuring and cutting all the lengths of wire I would need, and sorting them based on what the wires would connect to. The schematic is below.

alt text

Anyone who has pulled cable/wires knows how big of a pain this can be, and this situation was no different. Taping the wires to a straightened coat-hanger or a string proved to be the easiest method of getting the wires through the various sections of the lamp. Because the APA102 LEDs require that they be daisy-chained to function on the same bus, an extra set of data and clock wires for the outgoing signals from the first and second ring were needed - this increases the wire count for those two lamp heads by two.

There were some sharp edges of metal on the inside of the collector where each of the neck pipes joined. These edges could easily strip the sheathing from a wire or even cut the wire completely - I taped the edges I could reach.

Once all of the wires were pulled through the necks and the collector, I taped all the wire ends to the nearest surface to prevent the wires from being pulled out accidentally when pulling the other ends.

alt text

Next I cut and bent the brackets. I worked around the pre-drilled holes needed and cut just that portion from the rest of the bracket. Because the lamp head is round, and the bracket would need to sit more or less flush against the inner wall, I cut some wedges out of the sides of the bracket and bent the piece into a 90-degree “V” shape. After a couple tweaks and bends, the bracket seemed to fit well enough.

alt text

It was now time to assemble each of the lamp heads. The wires had to be pulled through the mounting hole of the lamp head and all of the other retaining parts before I could begin soldering the components to the ends. I found laying the parts out in the order that the wire had to pass through them to be helpful. In this case, the wire bunch had to pass through each part in this order: swivel (one half), swivel-elbow, lamp head, bracket, washer, lock washer, retaining nut.

Before I secured the bracket down with the retaining nut, I connected a couple 3/8-inch aluminum standoffs together and fixed them to the bracket, because I wasn't going to have room to secure the standoffs to the bracket once the bracket was in place. After the retaining nut was secured to the elbow I began soldering the potentiometer and LED ring to the wires. I chose to solder and install the trimpot first, as this part had to poke out the back of the lamp head, and like the standoffs on the bracket, I wouldn't be able to secure the trimpot in place with the LED ring installed.

alt text

The trimpot needs a power signal, a ground signal and an output signal, while the LED ring needs a power signal, a ground signal, a data in, a clock in, a data out (first two rings) and a clock out (first two rings).

I powered the trimpot and LED ring with 5V, which in the end was a mistake. In an effort to pull the least amount of wires through the lamp as possible, each lamp head was fed one 5V source wire and one ground. This meant I had to splice both the 5V and ground from the trimpot and the ring into the main power and ground sources. I chose to do this with some through-hole, 100-mil pitch headers (female and male) and once inserted, the headers were taped together to hold them in place - I figured this would make any disassembly or troubleshooting easier need be.

After securing the trimpot to the back of the lamp head, I stripped the ends of the wires going to the LED ring and soldered each to its respective pad. Last, I secured the LuMini ring to the end of the two stacked aluminum standoffs using a 4-40 screw. The same process was followed for the assembly of the other two lamp heads.

alt text

To complete the assembly of the collector and head assembly, I pulled the rest of the wires from the collector through the pole and the stand. The pole was threaded into the collector, and to complete the assembly of the lamp, all of the wires were soldered to the ESP32 Thing Plus under the stand.

Coding the ESP

The Arduino sketch below is the current running code on the ESP32:

#include <FastLED.h>

#define NUM_LEDS 60
#define DATA_PIN 18
#define CLOCK_PIN 5
#define short_pot 26
#define med_pot 25
#define long_pot 34
#define base_pot 39
#define short_ring 0
#define med_ring 20
#define long_ring 40

CRGB lamp_leds[NUM_LEDS];

int SHORT_VAL = 0;
int MED_VAL = 0;
int LONG_VAL = 0;
int LAMP_HUE = 0;
int LAMP_SAT = 200;
int PREV_MED_VAL = 0;
int PREV_LONG_VAL = 0;
int PREV_LAMP_HUE = 0;

void setup(){

  LEDS.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(lamp_leds, NUM_LEDS);

void loop(){
  //pull HUE from stand trimpot and pull VALUE from each lamp trimpot
  LAMP_HUE = pot_read(base_pot);
  SHORT_VAL = pot_read(short_pot)-20;
  MED_VAL = pot_read(med_pot)-20;
  LONG_VAL = pot_read(long_pot)-20;
  if(SHORT_VAL < 0) SHORT_VAL = 0;
  if(MED_VAL < 0) MED_VAL = 0;
  if(LONG_VAL < 0) LONG_VAL = 0;

  Serial.print("LAMP HUE = ");
  Serial.print("SHORT = ");
  Serial.print("MED = ");
  Serial.print("LONG = ");

  //check if current trimpot readings are different than the previous
     (PREV_MED_VAL != MED_VAL) ||
      if(LAMP_HUE == 0){
        //set ring output to white
        //set ring output to trimpot ADC value
      //set previous values read

//math on trim signal translating into range of 0-255
int pot_read(int pot){
  long VAL = 0;
  for(int i = 0; i<1000; i++) VAL += analogRead(pot);
  VAL = VAL/1000;
  int CAL_VAL = VAL/16;
  return CAL_VAL;
//sets LED settings
void populate_led_settings(int ring_start, int hue,int sat,int val){
  for(int i=ring_start; i<ring_start+20; i++){
    lamp_leds[i] = CHSV(hue, sat, val);

I opted to use the FastLED library because of its ease of use, and huge range of LED support and functionality. This was also my first time using the CHSV LED setting structure, which I found to be much more intuitive than the standard RGB structure. The above code functions well enough, but is far from perfect - this could be said for the lamp as a whole.

alt text

Using a 5V source for the trimpots was a mistake. First, it's possible to damage the ESP32 by feeding more than VDD+0.3V to any of the GPIO. Second, the ESP32 functions at a 3.3V logic level, which means the chip ends up clipping any trimpot signal voltage that exceeds 3.3V, shortening the usable signal window of the trimpot. If I had fed the trimpot a 3.3V signal I could see greater resolution.

alt text

In the meantime, the microcontroller will likely be switched to a ATmega328-based board running at 5V. Some of the math in the lamp sketch will have to be adjusted to account for the difference in ADC bit count, but it's a safe quick fix. Running a 3.3V source through the lamp and returning to the ESP32WROOM is the goal in the end.

All in all, the project was fun, and it feels good saving an old lamp. Tell us about some of your reused and recycled projects!

comments | comment feed

Enginursday: Keycode Security Starter, Part 1

via SparkFun: Commerce Blog

If you are like me, you enjoy the charm of driving an older vehicle. The mechanical feedback from the car is more organic. You aren’t surrounded by safety and driver aid systems that jump at the opportunity to correct your oh-so human actions. These cars were born in an era when manufacturers strove to have their own look. Shoot, you still get to plug the key into the ignition! You get the point, but as much as the above is appealing, there are many shortcomings in older vehicles, one of the primary being security.

Nowadays, most cars come with keyless ignition systems as standard equipment. This technology has been used in the industry since the late nineties in high-end automobiles, and only in the last decade or so has this system made its way to the masses. These systems can certainly come with their own set of headaches, but they do make auto theft much more difficult when using less tech-savvy methods.

My goal here is to create a keycode-based security system for starting my 80’s-era soon-to-be daily driver.

Disclaimer: the motor for said daily driver is still not actually in the car, so installation of this system will be covered in a future post. This system is designed to function with a starter circuit found in a 1980’s-era Volvo.

The primary motivations behind installing this system are to disable the ability to start the vehicle without entering the proper keycode, and to make the act of “hot-wiring” the vehicle much more difficult. The intention is to be as non-invasive as possible, so this system does not require the removal of any OEM parts included in my vehicle’s starting circuit.


The photo below illustrates the concept. Lets walk through it and talk about some reasoning.

alt text

In this basic implementation I am using the car battery to supply power to my microcontroller. In this case I’m opting to use the Sparkfun Thing Plus – ESP32 WROOM . I chose this board because of its potential – most basic microcontroller boards could perform the task needed, but I want to keep adding features and capabilities to this system, and the wireless and battery capabilities offer a lot of feature expansion. If I were simply installing the system depicted in the picture without the intention of adding to it, I might have opted for the less expensive Arduino Pro Mini.

alt text

Power is supplied to the microcontroller after the ignition switch, which, if functioning properly, should prevent the board from being powered up when the ignition switch is in the OFF position. This will keep the microcontroller from draining the car battery while the car is not in use and the battery is not being charged by the alternator. In the future, the onboard JST and LiPo charger of the Sparkfun Thing Plus could come in handy.

alt text

Now, I can’t just supply my Sparkfun Thing Plus with 12V from the ignition, so I’m using the Sparkfun Buck-Boost Converter to regulate that voltage down to 5V, which will then be routed to the Sparkfun Thing Plus’s VUSB pin. I will likely be placing a 1A or 500mA fuse between the 12V supply of the ignition and the Buck-Boost board. This should protect my ignition circuit in the chance that something I have added shorts.

alt text

From there I am utilizing the Sparkfun Qwiic Keypad – 12 Button as my HID device. This will live in the cabin of the car and will be used to enter the keycode. I’m connecting the keypad to my Thing Plus with a 100mm Qwiic Cable.

alt text

The next and most integral component is the Sparkfun Qwiic Single Relay. This board uses a ATTiny85 to act as an I2C slave and controls the the relay, allowing the user to open and close the relay using I2C communication. The Qwiic Relay will be acting as another switch on the starter solenoid power cable running from the ignition switch to the starter solenoid. When the relay is open, it should prevent current from reaching the starter solenoid. By controlling the current path to the starter solenoid, I can prevent the starter from engaging, and thus prevent the car from being started (in most cases).

Because this component will be under the hood, I opted to use some 22AWG wire to connect my Thing Plus to the Qwiic Relay. I will likely end up using some heat shielding on the wires and an enclosure for the Qwiic Relay to protect the parts from the heat of the engine bay and the elements.

alt text

I also want to include an option to bypass the Qwiic Relay. To do this, I’m going to use this toggle switch rated for 20A and 12V, which will be wired up in parallel with the Qwiic Relay on the starter solenoid control line.

Placing both the Qwiic Relay and the toggle switch under the hood should make hot-wiring the car much more difficult, requiring the would-be thief to go under the hood to reconnect the starter solenoid control line. Or just flip the switch... if they can find it.

At this point, it’s worth mentioning that I will be using at least 8AWG stranded wire to connect the Qwiic Relay and the toggle switch to the starter solenoid control line. This gauge of wire is large enough to safely handle the current of the starter solenoid control line, and should be available at any automotive parts store.


alt text

Above is a demo using a RedBoard Qwiic and a Qwiic Keypad to successfully close the Qwiic Relay when the proper keycode is entered. In this case the code is “1243.”

Below is the sketch I am using in the demo above:

#include <Wire.h>
#include "SparkFun_Qwiic_Keypad_Arduino_Library.h" 

#define COMMAND_RELAY_OFF     0x00
#define COMMAND_RELAY_ON      0x01

const byte qwiicRelayAddress = 0x18;     //Default Address

KEYPAD keypad1; //Create instance of this object

const char keyCode[] = {'1','2','3','4'};  //enter code here

char userEntry[] = {0, 0, 0, 0}; // used to store the presses coming in from user
boolean userIsActive = false; // used to know when a user is active and therefore we want to engage timeout stuff

#define TIMEOUT 30 // 100s of milliseconds, used to reset input. 30 equates to 3 second.
byte timeOutCounter = 0; // variable this is incremented to keep track of timeouts.

byte userEntryIndex = 0; // used to keep track of where we are in the userEntry, incremented on each press, reset on timeout.

#define stat_LED 13

void setup() {


  Wire.begin(); // join the I2C Bus

  if (keypad1.begin() == false)   // Note, using begin() like this will use default I2C address, 0x4B. 
                  // You can pass begin() a different address like so: keypad1.begin(Wire, 0x4A).
    Serial.println("Keypad does not appear to be connected. Please check wiring. Freezing...");
    while (1);


  digitalWrite(stat_LED, HIGH);
  digitalWrite(stat_LED, LOW);

  Serial.println("Car Starter ready for operation!");
  Serial.println("Keypad Car Starter Menu:");


void loop(void) 

  keypad1.updateFIFO();  // necessary for keypad to pull button from stack to readable register
  char button = keypad1.getButton();

  if (button == -1)
    Serial.println("No keypad detected");
  else if (button != 0)
    userEntry[userEntryIndex] = button; // store button into next spot in array, note, index is incremented later
    userIsActive = true; // used to only timeout when user is active
    if (checkEntry() == true)
      digitalWrite(stat_LED, HIGH);
      Serial.println("\n\r\n\rReady to start!");
      userIsActive = false; // don't display timeout stuff.
    if ( userEntryIndex == sizeof(keyCode)) userEntryIndex = 0; // reset
    timeOutCounter = 0; // reset with any new presses.

  delay(100); //10 is good, more is better, note this effects total timeout time


  if ((timeOutCounter == TIMEOUT) && (userIsActive == true)) // this means the user is actively inputing
    Serial.println("\n\r\n\rTimed out... try again.");
    timeOutCounter = 0; // reset
    userEntryIndex = 0; // reset
    userIsActive = false; // so we don't continuously timeout while inactive.

boolean checkEntry()

  for (byte i = 0 ; i < sizeof(keyCode) ; i++)
    if (userEntry[i] == keyCode[i]); // do nothing, cause we're only looking for failures
    else return false;
  return true; // if we get here, all values were correct.

// "clear" entry with all spaces
void clearEntry()
  for (byte i = 0 ; i < sizeof(userEntry) ; i++)
    userEntry[i] = 0; // fill with spaces

void printEntry()
  Serial.print("UserEntry: ");
  for (byte i = 0 ; i < sizeof(userEntry) ; i++)

// RelayOn() turns on the relay at the qwiicRelayAddress
// Checks to see if a slave is connected and prints a
// message to the Serial Monitor if no slave found.
void relayOn() {

// RelayOff() turns off the relay at the qwiicRelayAddress
// Checks to see if a slave is connected and prints a
// message to the Serial Monitor if no slave found.
void relayOff() {

// testForConnectivity() checks for an ACK from an Relay. If no ACK
// program freezes and notifies user.
void testForRelayConnectivity() {
  //check here for an ACK from the slave, if no ack don't allow change?
  if (Wire.endTransmission() != 0) {
    Serial.println("Relay does not appear to be connected. Please check wiring. Freezing...");
    while (1);

Maybe I'm overestimating the desire to steal this car? Nope, the desire is there... I see it in their eyes.

Stay tuned for part two, where I detail a step-by-step installation in the vehicle. In the meantime, let us know about hacks you have made on your vehicle, the issues you encountered and what you have planned next.

comments | comment feed

Using Eagle Configuration Script Files: How to Make Eagle Yours

via SparkFun: Commerce Blog

Let's talk about Eagle Configuration Scripts: how to use them, and why using your own can make your Eagle experience more enjoyable and efficient.

Let me preface this by saying that there is more I do not know about Autodesk's EAGLE PCB Design Software than there is that I do. That said, this is just a quick explainer, and there will be plenty left unsaid about using Eagle scripts.

If you are new to Eagle or unfamiliar entirely, check out these tutorials to help you get started:

What is a Configuration Script?

Put simply, it's a file used to configure an instance of Eagle with specific settings when opened.

When an instance of an Eagle editor is opened, Eagle accesses a configuration script file (eagle.scr). The configuration script contains a series of commands written in human readable text that change the settings for any instance of an Eagle editor workspace when opened. These include: BOARD Editor, SCHEMATIC Editor, LIBRARY Editor, DEVICE Editor, PACKAGE Editor and SYMBOL Editor. By changing the set of commands within the configuration script, the user can customize the settings of any of the aforementioned Eagle editors without the tedium of having to manually change the settings every time you open up an instance of Eagle.

Perhaps the most valuable feature of a personalized configuration script is the ability to setup a hotkey assignment map and workspace that caters to how you use Eagle. Whether you are designing schematics, designing boards, designing both or just reviewing designs, you can tailor the configuration of Eagle to allow you to work more efficiently.

Eagle is distributed with a default configuration script; it sets some default layers to be used, sets the unit(s) of measure, sets the grid spacing and calls some .ulp files, plus a few more things. Check it out below:

# Configuration Script
# This file can be used to configure the editor windows.
# Uncomment this if you want a set of useful default shortcuts!
#SCRIPT default-assign.scr;

MENU '[bin/designlink.svg] Search and order : Run designlink-order.ulp -general;'\
    '[bin/pcb-service.svg] PCB Service : Run pcb-service.ulp;'\
DISPLAY = 'Preset_Top' None 1 17 18 19 20 21 23 25 39 41 51;
DISPLAY = 'Preset_Bottom' None 16 17 18 19 20 22 24 26 40 42 52;
DISPLAY = 'Preset_Standard' None 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25     26 39 40 41 42 51 52;

Grid Default;
Change Width 0.006in;
MENU '[bin/designlink.svg] Search and order {\
                                          General : Run designlink-order.ulp -general; |\
                                         Schematic : Run designlink-order.ulp; \
     '[bin/LTspice.svg] LT Spice simulation {\
                    Export: RUN ltspice.ulp /E; |\
                    Export Setup: RUN ltspice.ulp /E /S; |\
                    Export Group: RUN ltspice.ulp /E /G; |\
                    Import: RUN ltspice.ulp /I; \
     }' \

MENU '[bin/designlink.svg] Search and order : Run designlink-order.ulp -general;'\
     '[bin/LTspice.svg] LT Spice simulation {\
                  Export: RUN ltspice.ulp /E; |\
                  Import: RUN ltspice.ulp /I; \
     '[bin/pads-pcb.svg] PADS package import : RUN import-pads-powerpcb-v5;' \

Grid Default;
MENU '[bin/designlink.svg] Search and order : Run designlink-order.ulp -general;' \
     '[bin/LTspice.svg] LT Spice simulation {\
                  Export: RUN ltspice.ulp /E; |\
                  SpiceOrder : RUN spiceorder.ulp; |\
                  SpiceModel: ATTRIBUTE SPICEMODEL |\
                  Value2: ATTRIBUTE VALUE2 |\
                  Import: RUN ltspice.ulp /I; \
     '[bin/pads-pcb.svg] PADS package import : RUN import-pads-powerpcb-v5;'\

Grid Default On;
Change Width 0.010in;
MENU '[bin/LTspice.svg] LT Spice simulation {\
                  Export: RUN ltspice.ulp /E; |\
                 SpiceOrder : RUN spiceorder.ulp; |\
                 Import: RUN ltspice.ulp /I; \

Grid Default On;
Change Width 0.005in;
Change Size 0.050in;
MENU '[bin/LTspice.svg] LT Spice simulation {\
                  Import: RUN ltspice.ulp /I; \
     '[bin/pads-pcb.svg] PADS package import : RUN import-pads-powerpcb-v5;' \

This default Eagle configuration script by no means makes Eagle unusable, but you are stuck with some pretty basic configuration settings. We have a SparkFun Eagle Settings GitHub repository, which includes an Eagle configuration script that provides a good starting point for understanding how these scripts are used, and for personalizing your own.

If you are new to GitHub, below are a couple tutorials explaining what it is, and how it is used:

Below is a simple demo configuration script to use as an example. Let's quickly break down some of the script so that you can get started making or modifying your own!

# Demo Startup Configuration Script 
# This file is used to configure the editor windows.

##############GLOBAL Instructions##############
#Assign GLOBAL workspace specific hotkeys
Assign F7 'NAME';

##############BOARD EDITOR specific Instructions##############
#Assign BRD workspace specific hotkeys
Assign F7 'MOVE';

#Setup Grid
Grid inch 0.05 on;
Grid alt inch 0.005;

#changes background color of board to black

#add layers
LAYER 227 xtra_ref;

#Layer colors
#Set top layer to dark red
Set color_layer 1 4;   
#Set xtra_ref layer to blue-green
Set color_layer 227 11;  

# When opening, hide all layers, then show layers 1 2 15 16 17 18 19 20 21 22 23 24 45 51 227 228 229 230 231
display none; display 1 2 15 16 17 18 19 20 21 22 23 24 45 51 227 228 229 230 231; 

#Assign BRD workspace specific hotkeys
Assign F8 'move';

##############SCHEMATIC EDITOR specific Instructions##############

#Assign SCH workspace specific hotkeys
Assign F9 'Net';

#net definitions
CLASS 1 8_mil 8mil;
CLASS 2 10_mil 10mil;
CLASS 3 12_mil 12mil;
CLASS 4 15_mil 15mil;
CLASS 5 20_mil 20mil;
CLASS 6 25_mil 25mil;
CLASS 7 30_mil 30mil;

##############LIBRARY EDITOR specific Instructions##############

#Assign LBR workspace specific hotkeys
Assign F10 'Grid inch 0.05 on; Grid alt inch 0.0001;';

#Set LBR workspace specific grid sizing
Grid mm 1 on;
Grid alt mm 0.1;

##############DEVICE EDITOR specific Instructions##############

Grid Default;

##############SYMBOL EDITOR specific Instructions##############

Grid Default On;
Change Width 0.010;

##############PACKAGE EDITOR specific Instructions##############

Grid Default On;
Change Width 0.005;

Anatomy of a Configuration Script

The configuration script is broken into a section for each variation of an Eagle editor, and each type is denoted by an editor-specific label. These labels instruct Eagle to run only the portion of the script that is between the editor type label being opened and the next editor label. This means the user can customize unique configuration settings for each editor type, most importantly hotkeys.

Eagle Editor Script Labels

Editor Type Editor Label
Schematic SCH:
Board BRD:
Library LBR:
Device DEV:
Symbol SYM:
Package PAC:

The portion of the script that lies above all labels is considered global. These instructions will run for any editor type opened, and will run before the instructions under the editor-specific label are run. Instructions under an editor label will supersede any global instructions that were run prior to the editor label.

To add a comment to your script, insert a pound symbol (#) followed by the text for your comment. Each new line of comments will require a new preceding pound symbol. A comment can live on the same line as a command, assuming it is stated after the command.

Eagle Commands

Eagle utilizes a built-in set of text commands that tell it to do anything from setting a layer's color to setting default wire widths. These commands can be used in place of any of the toolbar buttons, and the command structure and syntax is standardized within Eagle. Conviniently, the commands that can be entered into the command line field of an editor workspace are identical to those that are used to populate an Eagle configuration script.

  • As a side note - To utilize a command in a workspace, simply enter the command into the Eagle command line field with proper syntax and press enter. It should be said that some commands are specific to a certain type of editor, for example, a command specific to the schematic editor may return an error if entered into the command line of a board editor. This is also true of commands in a configuration script.

Lets look at a basic Eagle command used under the BRD: label in the above demo configuration script, and discuss the syntax and function. Checkout the command:

Grid inch 0.05 on;

This command tells Eagle to configure three settings:

  • inch - sets the unit of measure to be used for the grid to inches
  • 0.05 - sets the grid spacing to 0.05 units
  • on - sets the grid to be visible to the user

The command is "Grid," and the parameters are: "inch," "0.05" and "on." The semi-colon ";" tells Eagle that there are no more parameters. Remember, this command lives under the BRD: label, which dictates that this command will only be used when opening an instance of the board editor.

You can easily chain together parameters for one command by listing them separated by a space, and terminating the command by adding the semi-colon at the end. Here's another example:

DISPLAY 1 16 17 18 19;

This tells Eagle to make layers 1, 16, 17, 18 and 19 visible to the user. It's pretty intuitive. Interestingly, one could design an entire schematic with a string of text using Eagle's built-in commands.

Writing and Editing a Configuration Script

Eagle contains a built-in text editor that can be used for writing/editing SCRIPT and ULP files, but you can use any text editor that allows you to choose the file extension when saving your file. Eagle script files have a .scr file extension, which can create an issue when using Windows and an external text editor. Windows views a .scr file as a screensaver file, which means users may have trouble opening this file with a text editor. To fix this, go into the default apps setting menu (WINDOWS 10) or Program settings (WINDOWS 7) and set the default app for .scr files to whichever text editor you prefer.

Another point to take note of is that the configuration script file must be named "eagle.scr", and must live in the directory that is specified in the Directories: Scripts field.

Setting the Directory for your Configuration Script

To change/set any of the directory paths that Eagle uses to look for files, open up an instance of the Eagle Control panel, click on Options in the menu bar and click once more on Directories... in the drop-down. This will open the directories window, which houses the fields to set the file paths to the directories that contain files that you and Eagle want to use together. The Scripts field is where you set your configuration script file path.

alt text

For a detailed list of built-in Eagle commands, command descriptions and command usage examples, check out the Editor Commands section of the Eagle help utility, and for more information about Eagle scripts, check out the SCRIPT sub-section of the the Editor Commands section.

Eagle has a great built in HELP utility; it's an invaluable resource for novice and expert users alike. The HELP utility can be found on the far right of the menu bar on any main Eagle workspace window or the Eagle Control Panel.

Now go create your own Configuration Script!!!

...and be sure to let us know about your experiences using Eagle configuration scripts, plus any of your own tricks and tips, in the comments below.

comments | comment feed

Details from a Revision: the ACS712 Boards

via SparkFun: Commerce Blog

As a member of the Quality Control team, I am most often helping usher new PCB designs to the storefront ASAP, but on special occasions like this, I get to act as the primary engineer on a revision! What started as a simple “drop-in replacement” (famous last words) became quite a bit more involved. Join me as I highlight some of the hurdles and improvement opportunities uncovered along the way to our new, low current sensor, the ACS723!

In July 2017, SparkFun received news that Allegro Microsystems was retiring the venerable ACS712 family of Hall effect-based, current-sensing chips. We used this chip on two SparkFun products: the SparkFun Hall Effect Current Sensor Breakout and the Sparkfun Low Current Sensor Breakout.

SparkFun Hall-Effect Current Sensor Breakout - ACS712 SparkFun Low Current Sensor Breakout - ACS712

As both products were an asset to our sensor catalog, a revision was a must. Luckily, Allegro Microsystems had a recommended replacement chip family. With supplies of the ACS712 running out, the two design revisions were immediately re-prioritized to the top of the list, and work began.

Before any actual design work happens, it’s always a good idea to familiarize yourself with the product you’re revising. Let’s first build an understanding of the ACS712 current-sensing chip, then we will explore each of the designs that needed to be revised.

The ACS712 is the family of current-sensing chips previously offered by Allegro Microsystems. With the ability to measure AC and DC current up to 30A, this chip family was a great solution for many current-sensing applications. By using a linear Hall effect sensor, the ACS712 is able to isolate the circuit that is being measured from the circuit that is reading the output from the sensor, thus protecting your microcontroller. These sensors output a signal that is scaled to VCC, and with 0A flowing through the circuit measured, the sensor should output .5 * VCC. The ACS712 family is comprised of three different packages that can handle five, 20 or 30 amps. The sensor sensitivity changes depending on the sensor variation, with sensitivity decreasing as the chip’s amperage measurement range increases. In this case, we are concerned with the ACS712ELCTR-05B-T (5A variant), which has sensitivity rating of around 185mV/A measured.

Lets move on to the actual products that needed revising.

alt text

The Hall Effect Sensor Breakout is a simple breakout board that allows a user to solder wires or headers to through-holes to easily connect any of the pins on the ACS712 to an application.

alt text

The Low Current Sensor Breakout differs from the Hall Effect Sensor breakout in a couple ways.

  • First is the addition of an operational amplifier (op amp) circuit on the VOUT pin. The op amp and trimpots allow the user to set the VREF (voltage offset) and GAIN of the output signal, which can be very handy when measuring lower current levels as well as very slight changes in current.

  • The second major difference is that the Low Current version does not break out the FILTER pin. We placed a 1nF capacitor on the filter circuit to decrease noise at lower frequency bandwidths. Unfortunately, the 1nf cap on the FILTER pin limits the bandwidth to 34kHz; the full 80kHz bandwidth can be accessed by removing this cap.

Now let’s take a look at the chip family that Allegro Microsystems recommends as a replacement, the ACS723. The ACS723 family sets itself apart from the ACS712 with some additions and improvements.

  • The ACS723 family has even more chip options for your application, now with chips that are capable of accurately measuring ±40A. For our application we will use the ACS723LLCTR-05AB-T, which is rated to accurately measure ±5A.

  • Like the ACS712 family, the ACS723’s sensitivity levels are regulated by how much current the chip is rated to measure, however, all the chips in the ACS723 family now have improved sensitivity ratings when compared to the ACS712 family. In our case, the variant that is rated to measure ±5A now has a better sensitivity rating of 400mV/A measured compared to the previous, which had a rating of 180mV/A measured.

  • Another improvement with the new chip family is the method in which you select bandwidth and filtering. The “FILTER” pin on the ACS712 chips has been renamed “BW_SEL” on the ACS723 chips, which stands for “bandwidth select” and functions a bit differently. Instead of placing a filter capacitor on the FILTER pin to clean up the output signal, you now pull the BW_SEL pin to VCC or GND to select LOW or HIGH frequency bandwidth (respectively). The ACS723’s LOW frequency bandwidth setting limits the chip’s bandwidth to 20kHz, but provides a low noise signal from the sensor. The HIGH frequency bandwidth setting allows the sensor to read its rated bandwidth of up to 80kHz, but does not provide a low noise output signal.

That about covers the major differences between the two chip families. On to the fun part of this project, the revision.

When scoping a revision for any product, I find it handy to work from a list of questions to ask of the design. This can aid in assessing the product design, quantifying the potential work needed and exploring how to make the product better. Below is a list of categories and some of their associated questions:

Product aesthetics:

  • Could the silkscreen labels on the PCB be more legible or easier to interpret?
  • Is there silk on both sides of the board? If not, do we want silk on both sides of the board?
  • Does the product fit in with the general aesthetic of our products and product lines?

Product function:

  • Is the product up-to-date with current and/or popular connectors/termination points?
  • Could any components be swapped with newer components that enhance function and/or usability?
  • Could any of the components be updated to use more modern, less expensive parts to lower the BOM cost?
  • Could the general shape and/or design of the PCB enhance the product’s usability?

Product DFM (Design for Manufacture):

  • Do we see abnormal mounting or population errors due to old landings/package designs?
  • Could we re-situate components on the PCB to allow for faster manufacturing and easier rework?
  • Are component landings conducive to performing fast and accurate automated optical inspections?

Design Files:

  • Are all of the components in the design up to date and in the SparkFun Eagle libraries?
  • Do the Eagle files adhere to SparkFun’s aesthetic?

Customer Recommendations:

  • Have you considered recommendations by customers?
  • Have you checked with your support teams regarding the product?
  • Is the product something that customers and the community want?

It’s pretty interesting doing a deep dive on designs this old; in this case, both have been available for 10 years, and both really show their age.

We did make plenty of aesthetic and physical changes to the design, but I would like to focus on one of the larger functional enhancements, and a discovery made while testing the prototype of the Low Current version.

Bandwidth Selection re-thought:

Being able to adjust the bandwidth of the output signal of these chips is a nice feature – it allows the user to tailor the product to suit the application, such as reducing noise when using high gains. This is certainly a feature we wanted to extend to the user.

alt text

The ACS712 required a filter capacitor be removed from the FILTER pin for higher bandwidth operation. Removing an SMD capacitor can be a bit of a pain without the correct tools, specifically a hot-air rework station. Hot-air rework stations are expensive, and can be tricky to use for the inexperienced. On top of that, if the capacitor was removed entirely, the user would need to store or have additional capacitors if they ever wished to return the product to its original functionality.

alt text

The new ACS723 Breakout (Low Current) simplifies bandwidth selection by adding a jumper and a pull-up resistor to the BW_SEL pin. This allows the user to simply close the jumper (pulling the pin LOW) to achieve a high bandwidth signal, or leave the jumper as is (tied to VCC through a pull-up resistor) to utilize the default low-bandwidth, high-filter setting. Now this board requires no hot-air rework to switch the bandwidth, and can easily be switched back and forth without having to keep track of small components.

When referring to the ACS723 datasheet, Allegro recommends the BW_SEL pin be connected directly to VCC or GND. In order to utilize a select-able jumper, I was forced to pull the BW_SEL pin up to VCC through a pull-up resistor, which was a bit of a gamble.

alt text

I wasn’t sure if the BW_SEL pin needed to sync current in order to properly function. Luckily, in testing the prototype we discovered that the pull-up resistor to VCC worked, and successfully activated the filtration cap during lower bandwidth operation. Watching the output signal with an oscilloscope, it was clear that the signal had visibly less noise when the BW_SEL jumper was left open versus being closed.

alt text

Dialing in the Op Amp and GAIN:

Now, I’m sure many of you have heard the term “drop-in replacement,” and perhaps some of you have experienced woes when interpreting that term literally. I’ve found this term is often subject to some caveats, and shouldn’t be taken literally at all. When beginning the project it was said that the ACS723 is a drop-in replacement for the ACS712; while this is true in a part package sense, the cross-over functionality is greatly dependent on the circuits around the chip. In the case of the ACS723 Breakout Low Current, some of the surrounding circuitry needed to be adjusted in order to achieve functionality similar to the Low Current Sensor using the ACS712.

The ACS723 Breakout Low Current utilizes an op amp circuit to increase the gain of the signal that the ACS723 is outputting. The detail that is important here is the mV/A sensitivity rating of the output signal. The ACS712 has a sensitivity of 180mV/A measured, while the ACS723 has a sensitivity of 400mV/A measured, giving the ACS723 a much greater sensitivity rating, and allows for higher resolution than its predecessor. When I ordered prototypes, I left the op amp components the same. This was a mistake, and not ideal for functional performance. Here is why:

The op amp circuit in the original ACS712 design has a feedback resistor with a value of 47K, while the input to the op amp (signal output from the ACS712) was routed through a 1k resistor in series with a 10K trimpot. When the trimpot was positioned to apply near-zero impedance on the input, the op amp output signal would have a x47 gain when compared to the op amp’s input signal. This seems all dandy - who doesn’t like more gain on a very small signal? Alternatively, when the trimpot was positioned to add 10K of impedance on the input, the output signal would now have a gain of about x4.27 when compared to the op amp’s input signal. This is the minimum amount of gain you can set the op amp to. So what does this mean when when you are actually measuring current? Well, if the ACS712 is outputting 180mV/A measured, that means that if you have the gain set to x4.27, the op amp will now output 768.6mV/A. If you have set the VREF trimpot so that the board is outputting 0V when measuring 0 amps, you should have no clipping of the signal of the op amp output when reading in the range of +0 to +5Amps with an input on your microcontroller functioning at a 5V logic level.

Low Current Sensor Breakout - ACS712

Current Measured Output Signal GAIN
1A 0.77V x 4.27
2A 1.5V x 4.27
3A 2.3V x 4.27
4A 3V x 4.27
5A 3.8V x 4.27

While measuring the highest amperage that the chip is rated for, the VOUT signal is well within the readable range of a 5V logic level micro controller, i.e. you don’t experience any clipping of the signal during reads.

Now, some of you can probably guess where this is going. When you use this same op amp circuit and the feedback resistors with the ACS723, you end up with some drastically larger output signal voltages.

Current Sensor Breakout - ACS723 (Low Current)

Current Measured Output Signal GAIN
1A 1.7V x 4.27
1A 0.8V x 2
2A 3.4V x 4.27
2A 1.6V x 2
3A 5.1A x 4.27
3A 2.4V x 2
4A 6.8A x 4.27
4A 3.2V x 2
5A 8.5A x 4.27
5A 4V x 2

As you can see, when measuring 5A you are well beyond the readable limit of a 5V micro controller. Without a voltage divider you will not be able to accurately measure up to 5A. Ideally, we want to be able to measure the max amperage the chip is capable of reading without any clipping at the minimum GAIN, without using any other hardware or components.

To fix this issue, I replaced the 47K feedback resistor with a 22K, and now the signal is back in the readable range of a 5V microcontroller. The op amp now has a minimum gain of x2 and a maximum gain of x22. This means we also get slightly higher sensitivity at minimum gain (800mV/A) versus the ACS712 Low Current Sensor’s (768mV/A).

In the end, our ACS712-based current sensors live on through the ACS723, and with updated features and performance. Intentionally, this post only covers some of the more interesting details of the revisions. If you would like to dive into the minutia, I recommend downloading all four Eagle designs and comparing them. As always, feedback is appreciated – please post any thoughts in the comments below, and if you have any revision stories to share, we’d love to hear them! I’d also like to mention that if you have any revisions you’d like to see, please post them here or directly on the specific product page. In addition to handling EOL situations like this, we are always interested in revising products to make them better. Thanks for reading, and I look forward to sharing the details of another revision sometime soon!

comments | comment feed