Author Archives: Eric Orosel

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

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

Hardware:

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.

Results:

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

Disassembly

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.

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_SHORT_VAL = 0;
int PREV_MED_VAL = 0;
int PREV_LONG_VAL = 0;
int PREV_LAMP_HUE = 0;

void setup(){
  pinMode(short_pot,INPUT);
  pinMode(med_pot,INPUT);
  pinMode(long_pot,INPUT);
  pinMode(base_pot,INPUT);

  LEDS.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(lamp_leds, NUM_LEDS);
  LEDS.setBrightness(LAMP_SAT);
  Serial.begin(9600);
  Serial.println("Hello?");
}

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;

  //debug
  Serial.print("LAMP HUE = ");
  Serial.println(LAMP_HUE);
  Serial.print("SHORT = ");
  Serial.println(SHORT_VAL);
  Serial.print("MED = ");
  Serial.println(MED_VAL);
  Serial.print("LONG = ");
  Serial.println(LONG_VAL);


  //check if current trimpot readings are different than the previous
  if((PREV_SHORT_VAL != SHORT_VAL) ||
     (PREV_MED_VAL != MED_VAL) ||
     (PREV_LONG_VAL != LONG_VAL) ||
     (PREV_LAMP_HUE != LAMP_HUE)){
      if(LAMP_HUE == 0){
        //set ring output to white
        populate_led_settings(short_ring,LAMP_HUE,0,SHORT_VAL);
        populate_led_settings(med_ring,LAMP_HUE,0,MED_VAL);
        populate_led_settings(long_ring,LAMP_HUE,0,LONG_VAL);
      }
      else{
        //set ring output to trimpot ADC value
        populate_led_settings(short_ring,LAMP_HUE,LAMP_SAT,SHORT_VAL);
        populate_led_settings(med_ring,LAMP_HUE,LAMP_SAT,MED_VAL);
        populate_led_settings(long_ring,LAMP_HUE,LAMP_SAT,LONG_VAL);
      } 
      //set previous values read
      PREV_SHORT_VAL = SHORT_VAL;  
      PREV_MED_VAL = MED_VAL;
      PREV_LONG_VAL = LONG_VAL;
      PREV_LAMP_HUE = LAMP_HUE;
      FastLED.show();
     }
     delay(50);
}

//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.

Concept

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.

Mini DEMO

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() {

  Serial.begin(9600);

  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);
  }

  testForRelayConnectivity();
  relayOff();

  pinMode(stat_LED,OUTPUT);
  digitalWrite(stat_LED, HIGH);
  delay(250);
  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");
    delay(1000);
  }
  else if (button != 0)
  {
    //Serial.print(button);
    userEntry[userEntryIndex] = button; // store button into next spot in array, note, index is incremented later
    printEntry();
    userIsActive = true; // used to only timeout when user is active
    if (checkEntry() == true)
    {
      relayOn();
      digitalWrite(stat_LED, HIGH);
      Serial.println("\n\r\n\rReady to start!");
      clearEntry();
      userIsActive = false; // don't display timeout stuff.
      delay(1000);
      digitalWrite(stat_LED,LOW);
    }
    userEntryIndex++;
    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

  timeOutCounter++;

  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
    clearEntry();
    //printEntry();
    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.println();
  Serial.print("UserEntry: ");
  for (byte i = 0 ; i < sizeof(userEntry) ; i++)
  {
    Serial.print(char(userEntry[i]));
  }
  Serial.println();
}


// 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() {
  Wire.beginTransmission(qwiicRelayAddress);
  Wire.write(COMMAND_RELAY_ON);
  Wire.endTransmission();
}


// 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() {
  Wire.beginTransmission(qwiicRelayAddress);
  Wire.write(COMMAND_RELAY_OFF);
  Wire.endTransmission();
}


// testForConnectivity() checks for an ACK from an Relay. If no ACK
// program freezes and notifies user.
void testForRelayConnectivity() {
  Wire.beginTransmission(qwiicRelayAddress);
  //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;
#

BRD:
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;

SCH:
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; \
     }' \
;

LBR:
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;' \
;

DEV:
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;'\
;

SYM:
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; \
    }'\
;

PAC:
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##############
BRD:
#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
SET PALETTE 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##############
SCH:

#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##############
LBR:

#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##############
DEV:

Grid Default;

##############SYMBOL EDITOR specific Instructions##############
SYM:

Grid Default On;
Change Width 0.010;

##############PACKAGE EDITOR specific Instructions##############
PAC:

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