Pinball: The PCB Version 1.0 – Fail

I got the boards back and assembled several of them… and they do not work.  It has been a really really frustrating few days trying to figure out what was going on.  I started with the assumption that I had a soldering problem so I soldered it and resoldered it about 10 times.   I used the soldering iron, I used hot-air, I reflow’ed the board, and I did 3 different complete board re-dos.  None worked.  I really wanted this to work before Maker Faire.

Finally I gave up and sent my board to our kit team in India.  This is not such a simple thing to do as you need to have commercial invoices for all of the stuff that I sent them… after getting it rolling and patiently waiting for three days for Fed-Ex to get it through all of the customs hoops etc. I get this email from the Kit Manager:

email

Damn damn damn… I know that I double checked the package.  That is such an amateur mistake… alway always always check your footprints.  But Ronak is right, here is a screen shot of the Eagle Layout which I clicked on Pin 2. (I rotate the image to make it line up with the data sheet)screen-shot-2016-09-24-at-8-16-22-am

And it matches the the picture from the data sheet for the module… However… notice that it says “Bottom View” which means I flipped it.

screen-shot-2016-09-24-at-8-14-43-am

Here is a screenshot of the package in the eagle library… sure enough. It is flipped.

screen-shot-2016-09-24-at-8-24-47-am

More evidence, here is the top view:

 

screen-shot-2016-09-24-at-8-13-47-am

So, I need to fix the package and then re-do the layout.  I start this process by making a new branch in git.

screen-shot-2016-09-24-at-8-41-00-am

Then open the library and the package:

screen-shot-2016-09-24-at-8-40-10-am

To make things easier I turn off all of the layers except for Top.  This allows me to easily click on each pad.  One thing that is a bit of a PITA is that you have to change of all of the pads to something else before you can change each one to what you want e.g. you can’t rename the pad currently named 1 to be 32 because there is already a 32.  So, what I do is rename each pad to the new name with an A on the end (see the image below).  Once that is done I go back around and remove the “A”s.

screen-shot-2016-09-24-at-8-51-18-am

Once my package is fixed, I update the library that I am using in my layout.

screen-shot-2016-09-24-at-8-59-55-am

Eagle immediately tells me that I have a problem… which is true, so true.

screen-shot-2016-09-24-at-9-00-20-am

Then I ripup all of the nets, which is so sad.  The problem is that all of the things I had on the left are now on the right and visa-versa so I need to think about the whole placement.

screen-shot-2016-09-24-at-8-57-45-am

Once I have ripped up all of the nets, I then cross probe all of the nets (In this case M1R which is also pin 31) to make sure that I have the connections in the right place.

screen-shot-2016-09-24-at-9-04-12-am

OK.  Looks good.  Not commit the changes and put them back to the github with a change request.

In the next post Ill talk about the new layout.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Printed Circuit Board Version 1.0

I am supposed to be good at this stuff.  What is this stuff?  Simple, everything engineering.  Unfortunately, I suck at PCB layout.  This is something that I am loath to admit because it is so frustrating. There it is.  But I need a PCB to make this work, so here we go again.  What also sucks is that I entitled this post “Pinball: The Printed Circuit Board Version 1.0” because I know that it is going to take multiple versions.  I don’t know what the exact cause is going to be this time.  But it will be something.  Enough whining.  Onto the task at hand.

When you start from an empty board Eagle gives you the tantalizing picture of a blank board with the components you need laid out neatly.  All you need to do is move them onto the tabla rosa.

Screen Shot 2016-08-29 at 5.21.40 AM

Initially there are several constraints that I am trying to satisfy.

  1. I want the board to cost <$5 so it needs to be <5 Sq. Inches
  2. The Pinball machine has space on the front for something roughly the shape of a deck of cards (2.5″ x 3.5″)
  3. The power connector needs to be at the bottom
  4. The user interface needs to be at the right (buzzers, capsense buttons) because Billy is going to cover the left side with some acrylic.

We had originally thought about making a 3-D printed box for the design, but decided that it would be cool to be able to see the board.  It also saves several dollars in cost to get rid of the box.

All right, I suppose that it is time to get to it.  First I move all of the component from “off the board” onto the board.  They all need to appear inside of the dimension layer.  If you look at the pinball machine I want all of the wire to come from the top and then go down into the machine.  So I place the holes for the LEDs and the Switches at the top of the board.  I want the user interface to be on the right side of the board (since most of the world is right handed… sorry about the left handed people).  So, I place the capsense buttons and the reset button on the right side of the board.  The BLE Module needs to have the space under the antenna without a ground plane and without signals, so I decide to put it at the bottom of the board.  I decide that the I2C port for the LCD will go on the left side of the board as that will make the connection to the LCD on the left side of the pinball machine easier.  Finally I put the accelerometer and all of the stuff that it takes to run it on left left side as well.

screen-shot-2016-09-25-at-10-07-51-am

Once the placement is all done, it is time to route the signals.  I do this through a combination of the autorouter and manual routes.  After I get all of the routes done, I place GND via(s) all over the board to connect the top and bottom ground pours.

screen-shot-2016-09-25-at-10-06-25-am

When I click the rats nest button the pours happen and I can see that there are no unrouted nets.

screen-shot-2016-09-25-at-10-05-40-am

Next I  do the top silkscreen

screen-shot-2016-09-25-at-10-10-09-am

Finally the bottom silkscreen

screen-shot-2016-09-25-at-10-11-31-am

The last step is to re-check all of my printed circuit board rules (the subject of the next post).  Now that I have a printed circuit board I can send to OSHPark to be made.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Eagle Schematic

In the last bunch of posts I have talked about the main systems of the pinball machine electronics package.  Now it is time to assemble all of those pieces into a complete system on an Eagle schematic which you can find in the “eagle” directory on the github site.

I use the multipage capability of Eagle to partition the schematic into 7 pages.

  1. Main Page
  2. LEDs
  3. Switches
  4. Accelerometer
  5. Power
  6. Motors
  7. Test Points

The main page contains the

  1. PSoCBLE module:  Notice that I used every single pin except for VRef.  Also notice that I overloaded SWD-Clock and SWD-IO pins by attaching capsense buttons to those pins.  This means that I will never be able to debug and use Capsense at the same time.
  2. USB Connector:  When I was trying to figure out how to make the board less expensive my son suggested that everybody has a USB charger, so why don’t you just power the pinball machine with that?  I thought that this was a great idea as it eliminates a $5+ wall wart.
  3. Two buzzers.  These are super simple low cost 12mm through hole buzzers which are used by the MusicPlayer component.
  4. Two capsense buttons multiplexed to the SWDCLK and SWDIO pins of the chip.  Notice that they have a 560Ohm series resistor
  5. The reset button for the system which just pulls down the XRES when you press the button.  It also has the 10K pullup resistor which pulls up XRES when the button is not being pressed
  6. Pull-up resistors for the 5V I2C bus.
  7. A 5-Pin programming plug for the MiniProg-3 connected to SWDIO and SWDCLK and the Power/Ground
  8. A plug for the I2C LCD to connect to the I2C Bus

screen-shot-2016-09-25-at-6-44-48-am

Page two of the schematic contains two connectors for the LEDs which I talked about in detail in the Matrix LED Posts .  It also contains the current limiting resistors.  In order to save money in the BOM I am not going to actually put connectors into the 100mil center holes, but will let the kids learn to solder by attaching the wires directly into the holes with solder.

screen-shot-2016-09-25-at-6-45-06-am

Page three of the schematic contains the switch matrix connectors and diodes.

screen-shot-2016-09-25-at-6-45-20-am

I thought that it would be a really cool idea to have an accelerometer on the board to provide a tilt functionality.  This actually turned out to be a serious PITA because I couldn’t find a cheap accelerometer that was 5v.  So, in addition to the accelerometer I have to provide a level translator for the I2C bus (PCA9306) and a level translator for the Accelerometer interrupt line (the mostfet and pull-up resistors).  I also have to provide a 3.3v power supply (next page of the schematic)

screen-shot-2016-09-25-at-6-45-36-am

The 3.3v accelerometer requires a 3.3v power supply, so on this page I use an REG317 to create 3.3v from the VBUS power supply.

screen-shot-2016-09-25-at-6-45-54-am

In order to drive the two brushed DC motors I use a TB6621 motor driver chip that contains two H-Bridges.

screen-shot-2016-09-25-at-6-46-04-am

Finally I like to have test points on the board to measure stuff while I am assembling the board.

screen-shot-2016-09-25-at-6-46-15-am

In the next post Ill talk about the creation of the layout for the printed circuit board.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Motors + Hbridge

When Billy and I talked about making the electronics package for the Pinball machine, I suggested that it would be cool to have some motors.  Mr. Mechanical Engineer’s eyes lit up when I made that suggestion.  There are tons of things that the kids to could with a couple of controllable motors.  You could imagine conveyor belts, spinning obstacles, and all manner of lift systems.

I wanted to use inexpensive DC Toy motors.  The problem with most motors is that they require higher voltages (5-9 volts) and currents (250mA for the one that I wanted) than the PSoC (or generally any MCU) is capable of delivering.  Well that’s OK, it turns out there is a whole class of Power Management ICs (PMICs) which provide translation between an MCU and a Motor.  The one that I am going to use is called the TB6612.  This chip has dual Hbridges that help you control both the speed and direction of two motors.

First, the chip uses NMOS transistors configured as switches to let you control higher power (voltage and current) circuits.  Here is a picture of the input to the PMIC from the datasheet:

screen-shot-2016-09-25-at-8-15-00-am

Second you want to be able to control the speed and direction of the motor.  Here is a screen shot from the data sheet that shows the inputs and what happens with the motor.

screen-shot-2016-09-25-at-8-13-11-am

Here is a picture that shows you how the current flows through the Hbridge as well as showing the circuit that keeps you from short circuiting between the phases.

screen-shot-2016-09-25-at-8-16-46-am

So, how do you control the speed?  Simple, you use a PWM to create a train of pulses that have different duty cycles.  The greater the duty cycle, the faster the motor goes.  The lower the duty cycle, the slower the motor goes.

One last problem.  The chip requires IN1, IN2, PWM and Standby, but I want to only use two outputs from the PSoC.  So, what I decide to do is

  • Turn the standby off (so that the chip is always active)
  • Attach the PWM input to high so that the motor is always spinning
  • Attach In1 and In2 to the PSoC.  The PSoC will then set them to the correct value and PWM.

In the next post Ill start the process of turning all of the different blocks into a schematic that can then be turned into a printed circuit board.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

 

Pinball: The Music Player (Part 4)

In the previous three posts I created a Music Player component by building the symbol+schematics, making a public interface, and writing the firmware.  In this post I will show you the test program called “MusicTestComponent”.

In order to get access to the PinballComponents library project I first right click on my project and edit the dependencies.  Specifically, I click on the box that adds the “PinballComponents” as a dependency of the MusicTestComponent project.

screen-shot-2016-09-23-at-11-01-14-am

After setting up the dependencies you can then make a schematic with the MusicPlayer and a UART.  The UART will be used to trigger commands to be sent to the MusicPlayer Component.

screen-shot-2016-09-23-at-10-56-05-am

I start the main firmware by creating a test song called “scaleNotes” (lines 5-12).  I then turn that array of Notes into a Song by declaring  a Song and adding the scaleNotes to the song (lines 15-19).

screen-shot-2016-09-23-at-10-54-51-am

At the start of the program I turn on the interrupts and start the components (line 27-31).  Then I add my song to the component (so that it can play it) with line 33.

In the main loop of the program I grab characters from the UART and issue commands to the MusicPlayer component based on what button the users presses.

On lines 57-62 I have a debugging pinout that prints out the currently playing note number each time the note changes.

screen-shot-2016-09-23-at-10-55-10-am

Thats it.  In the next post I will start taking you through the process of designing the printed circuit board.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Music Player (Part 3)

In this previous posts I showed you the Schematic/Symbol and the public API for the Music Player.  In this post I will take you through the firmware.  The first section defines:

  • Parameters of the system, specifically the clock frequency and PWM prescaler (line 4-5)
  • The internal variables that are used to keep track with what is happening on the son (lines 8-12).
  • The notes for twinkle twinkle little star (Lines 22-43)
  • An array to hold songs (line 47-48)

screen-shot-2016-09-22-at-6-18-09-am

The GetNote function just returns the current songs currently playing note number.  I used this function when I was trying to debug the player.

The FrequencyToPeriod uses the settings of the PWM and the desired frequency to calculate the Period/Compare values to achieve the desired output.  The PWM has three parameters that change its output.

  • The input clock
  • The input prescaler (just a divider on the front end of the PWM)
  • The period (what you are trying to calculate)

screen-shot-2016-09-22-at-6-23-55-am

The next note function figures out the right settings for the PWM based on the desired frequency of the note, then sets up the PWM to the correct values (line 88-91), it then calculates how long to play the note (line 92).  Finally it sets thing up for the next note (line 97-101)

screen-shot-2016-09-22-at-6-20-46-am

The SysTickCallBack function controls the amount of time that

  • A note plays (lines 138-139)
  • The gap between the notes (lines 132-136)
  • The buzzer sounds (116-124) if the TWO_CHANNELS are enabled

screen-shot-2016-09-22-at-6-21-09-am

The Start function initializes all of the internal variables to turn off the songs.  The MusicPlayer uses the SysTick timer to keep track of how long the notes and the Buzzer have been on/off.

The Stop function turns off the Buzzers.

screen-shot-2016-09-22-at-6-21-31-am

The function PlaySong initializes all of the internal variables that are used to keep track of the song status.  It points at the first note, then it calls the NextNote function.  This function returns the ErrorCodes value which enables me to do a range check and existence check on the song number (lines 185-188).

The SetBPM changes the internal variable _BPM which is used to calculate the duration of notes.  This function also returns an ErrorCodes value after doing a range check.

The AddSong function allows the component user to define a new song and to assign it the list of Songs.

screen-shot-2016-09-22-at-6-26-49-am

The last section of code provides the buzzing functionality.  These function turn on and off the 2nd buzzer.  The first function turns on the 2nd buzzer at the requested frequency for either 0-means infinite time or a # of milliseconds.  Notice that this section of code only shows up if the user has turned on the second channel (line 230).

screen-shot-2016-09-22-at-6-34-43-am

In the next post Ill show you the test code for the component.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Music Player (Part 2)

After you have the symbol and schematic (look at the previous post) for the Music Player completed, the next step is to build the firmware to actually play the music.  This starts with building the public API in the MusicPlayer.h file.  I am not a musician… not even close.  When I was in 4th grade I tried to take up the trumpet, but the music teacher told me that I was terrible and should stop, so I did.  That was the last time I ever took crap advice from a teacher.

Anyway, I want a simple interface to

  • Define songs
    • Made up of an array of notes with frequency (in Hz), duration (as a fraction of a whole note = 64 counts)
    • With a known number of notes
    • With a default beats per minute (BPM)
  • Play songs
    • Start the song
    • Stop the song
    • Change the tempo of the currently playing song
  • Play buzzer tones
    • Turn on the buzzer at a frequency for a duration
    • Permanently turn on the buzzer
    • Turn off the buzzer

Lines 7-10 define the basic type called a Note which is the combination of a frequency and a duration.  To make things simple a WHOLE_NOTE is defined as 64 time units.  So, a half note is 32 counts and a quarter note is 16 counts etc.  You can see some common definitions on lines 20-22.

Lines 12-18 define some common notes which are frequently used to build up songs.  These are all from the middle octave of a piano keyboard.  I found the frequencies from a table on the internet.

Line 24-30 define a list of possible error codes that can be returned by my functions.  Using an enum is much safer than returning an error code with a #define because the compiler makes sure that you actually return a value with meaning.

Line 32-36 defines a Song which is a combination of an array of notes, the number of notes in the array and speed to play the song.

Finally lines 38-49 define the actual public functions.

screen-shot-2016-09-21-at-7-25-41-am

In the next post Ill take you through the firmware.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: The Music Player (Part 1)

After a few days off (Im sorry) I am back to it.  Every Pinball machine does lots of beeping, buzzing and music playing as will this one.  A very inexpensive way to make sound is to use a piezo-electric buzzer.  To make it “buzz”, you just drive a 50% duty cycle square wave into it at the frequency you want.  This is a perfect task for the PSoC4 BLE Timer Counter Pulse Width Modulator (TCPWM).  There are obviously limitations with this scheme, starting with you can only play one note at a time, and the notes can only be square (real sound has a much more complex waveforms).  But all of that is OK because the buzzer work OK and, as I said… they are cheap.  On the Pinball printed circuit board I have placed two buzzers, my thought was one would be used for buzzing and one would be used to play a song.

To make things easier for the main firmware I will build a component just like I did for the LEDs and the Switches.  Start by creating a new component by:

  • Click on the components tab
  • Right click on the “Pinball Component” library project and select “Add Component Item…”
  • Select “Symbol Wizard”, give the component the name “MusicPlayer” (exactly like I did in the LED and Switches components)

I thought that it would be nice for the MusicPlayer component to be able to select if it is a one or two channel player.  So, right click on the blank part of the symbol editor canvas and select “Symbol Parameters”.  Next add a bool parameter called “TwoChannels”

screen-shot-2016-09-20-at-6-28-32-am

To put the component in the correct place in the Component Browser right click the blank canvas, select “edit properties”, edit the”Doc.CatalogPlacement” and enter the placement of “Pinball/MusicPlayer/”

screen-shot-2016-09-20-at-6-43-51-am

Next, you need to create the schematic for the music player.  You do this by right-clicking on the “Pinball Component” project and adding a “Schematic” implementation.  Then add the default clocks, the TCPWMs and the pins.

screen-shot-2016-09-20-at-6-26-40-am

Earlier I added a component parameter called “TwoChannels”.  When this parameter is false, I want to remove the extra components.  With the help of the Cypress component manager I found out how to do this.  And it is simple.  Just add an expression to the TCPWM, Pin and Clock “CY_REMOVE” Parameter.  This parameter shows up on the “Built-in” tab for these three components (in fact all Cypress components).  When the value is “true” the component magically disappears.

screen-shot-2016-09-20-at-6-27-55-am

Next, I configure the TCPWM to have the prescaler turned on (which divides the input clock).  This is used to reduce the default 12MHz clock down to an easier to control 93.75Khz.

screen-shot-2016-09-20-at-6-27-11-am

In the next post Ill show you the firmware.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Switch Matrix Component (Part 3)

In order to build a test case for the SwitchMatrix component, I first create new project called “SwitchMatrixTest”.  Then I create a schematic with the component and a UART.  Notice that I draw the “external components” of the switch matrix, but I can’t hook it up to the actual component because I never created the external terminals for the SwitchMatrix component (bad Alan).

screen-shot-2016-09-11-at-8-53-54-am

Next I edit the main.c First, lines 4-5 are to flags that are set by interrupt service routines.  The switchedFlag is set by the component when you have registered your interested in a switch changing event.  The sysTimeFlag is set every 200ms by the sysTick ISR.

Lines 15-19 saves the status of the switch interrupt flags for use by the main loop.

Line 27-34 is a simple timer that I implement using the SysTick timer.  I set a flag every 200ms which I use to printout things on a regular basis in the main loop.

screen-shot-2016-09-11-at-8-55-11-amIn the main program I first start all of the components, interrupts etc in lines 43-47.  On lines 52-75 I process the user input and try out different functions of the component.

screen-shot-2016-09-11-at-8-56-20-am

Lines 79-84 causes the status of the switches to be printed out IF the switched flag is set.  The switched flag is set in the callback function switchedCallBack();

Lines 87-91 print out the status of the switches every 200ms based on the system timer.

screen-shot-2016-09-11-at-8-56-36-am

In order to get my SwitchMatrix component to call back when a rising/falling edge occurs, I need to register that call back in the cyapicallbacks.h.  I first make a forward declaration of the function on line 15.  Then I #define the “SwitchMatrix_SWITCHED_CALLBACK” which tells the component which function to call.

screen-shot-2016-09-11-at-8-58-15-am

In the next set of posts I will discuss the Music Player.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Switch Matrix Component (Part 2)

In the previous post I took you through the steps in creating the symbol and schematic for the Switch Matrix Component.  Next, we need to look at the firmware API.  First we will build the public interface to the component.  Ill start by adding “SwitchMatrix.h” to my component by

  • clicking on the components tab
  • right clicking on the “SwitchMatrix” component and selecting “Add Component Item…”

screen-shot-2016-09-11-at-7-56-01-am

  • Choosing “API–>API Header File”

screen-shot-2016-09-11-at-7-58-46-am

In the SwitchMatrix.h I define the public interface to the component.  For the switches you want to have:

  • A polling interface
  • An interrupt based interface

On line 6 I wanted a bit mask to represent the status of the switches.  When I setup things originally I was not sure how many bits I was going to support and I wanted to be able to change the length of the bit mask with just one #define.  Given that my switch matrix component can do 8 rows and 8 columns a.k.a. 64 switches I probably should have set this mask to uint64_t.  BUT when I started the work I didnt know that type existed so I just used uint32_t.  It is even a bit more confusing because Cypress provides the non CMSIS-CORE definition of uint8, uint16, uint32…  All that aside, if you  change the #define it will change for all of the switches.

On lines 8-13 I define a new type that defines the list of possible interrupts (No interrupt, rising edge, falling edge or both edges).

Line 15 defines the start interface.  This component uses the systick timer to run the state machine that sequences turning on/off of the switch rows/columns.  The “number” is which of the 4 Cypress SysTick interrupt vectors to use.

Line 16 returns the status of switch at row,column and returns 1 for active and 0 for inactive.

Line 17 returns the status of ALL of the switches into a bit mask

Line 18-21 defines the interrupt based interface to the switch matrix.

  • Line  18 request to be interrupted based on row,column
  • Line 19: clears the interrupt flags
  • Line 20: returns the falling interrupt flags
  • Line 21: returns the rising interrupt flag

The big question with the interrupt interface is: What function is called when an interrupt happens?  The answer is: I used the “cyapicallbacks.h” functionality that PSoC Creator provides for you (more to follow).

All of the bit masks that I used are of the form of [ r2c2,r1c2,r0c2 r2c1,r1c1,r0c1 r2c0,r1c0,r0c0 ]

Screen Shot 2016-09-06 at 7.53.19 AM

The next thing that you need to do is to implement the actual firmware for the system.  Start by adding “SwitchMatrix.c” to the component (using the same method detailed above except choose “API C File”.

On lines 4-9 I turn Symbol Parameters into #defines which can be used in my source code.  Remember that we let the user define the $NumCols, $NumRows and $RefreshInterval.

Line 10 is a neat way to make a bit mask of all 1’s up to a bit position.  e.g if you want 3’s aka 0b111 then you can do 2^3-1 = 7 = 0b111.  This bit mask is used to mask off the read bits from the pins.

Line 14 defines a variable which is the Current Column that you are looking at.  This changes every READ_INTERVAL/# of column ms and cycles through the columns.

Line 16 is an array of the bit masks of the status of each of the columns.

Line 17 holds flags for which rising and falling switches you are interested in for an interrupt.

Line 24-25 holds the status of which of the switches caused the interrupt.

Screen Shot 2016-09-06 at 7.54.40 AM

The SetInterruptMode function sets the bit mask for the rising or falling interrupt.  The $INSTANCE_NAME_MASK_TYPE is the type (in this case uint32_t) of the bit mask for switches.  On line 41-42 I turn off the interrupt.  Then the switch on line 44 resets the bit based on the input.

Screen Shot 2016-09-06 at 7.54.59 AM

The ClearInterrupt function just clears all of the interrupt flags (rising and falling).  It returns the state of the flags (before the reset).

Screen Shot 2016-09-06 at 7.55.58 AM

The function “SwitchCallBack” (which should have been defined static) is the main brains of switch sequencer. It is called every 1 ms by the SysTick callback.  Lines 92-94 lowers the frequency of doing something by only updating the status etc every “READ_INTERVAL/Column” ms.

Line 97 reads the digital input pins of the switch matrix.  It uses the row_mask to mask off the bits that are not being used.  It turns out that this was not needed because when you read a bus of pins the Cypress APIs automatically mask off the other bits.

Lines 100-105 builds a bit mask of the status of all of the bits.

Line 111-112: sets the interrupt flags by comparing the “nextStatus” with the “currentStatus”

Line 118 moves turns on the next column pins.

Line 124: Calls back if there is an interrupt.  It uses the “cyapicallbacks.h” to figure out what to call back.  This could have been done by registering a function pointer… but oh well that is what Cypress decided.  To use this you do a #define MatrixSwitch_SWITCHED_CALLBACK with the name of the function you want called.

Screen Shot 2016-09-06 at 7.56.17 AM

The next functions are just simple helper functions which return a status or start the component.

Screen Shot 2016-09-06 at 7.58.00 AM

In the next post I will show you some simple firmware to test the component.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Switch Matrix Component (Part 1)

In the post entitled “Pinball: Matrix LEDs Component” I took you through the steps to create an LED Component.  In this post I will take you through the steps to do the same thing, create a component, for the Switch Matrix that I talked about in the last post.  Since I did the LED component I figured out how to embed the pins into the component and have a variable number.  I am going to go back and fix the LED component.

The first step to create the Switch Matrix Component is to click on the “Component” tab so that you can create a new component in the “Pinball Components” library.

Screen Shot 2016-09-06 at 7.07.40 AM

Now, add a new component to the library by right clicking the “Pinball Components” library and selecting “Add Component Item…”

Screen Shot 2016-09-06 at 7.08.14 AM

Start by creating a Symbol for the “SwitchMatrix” component.  If you don’t want to draw all of the parts of the symbol then just use the automatic “Symbol Wizard”.

Screen Shot 2016-09-06 at 7.06.39 AM

Next, add three component parameters, which will be editable by the user of the component.  Do this by right clicking on the blank canvas part of the symbol editor and select “Symbol Parameters…”.  Add NumCols, NumRows, and RefreshInterval.  These will be usable in your source code as $NumCols, $NumRows and $RefreshInterval.

Screen Shot 2016-09-06 at 7.11.15 AM

Then, put the component into the right place in the component catalog by right clicking on the blank canvas in the symbol editor and selecting “Properties”

Screen Shot 2016-09-06 at 7.10.35 AM

Select the “Doc.CatalogPlacement” and type in the place where you want the component to show up in the Component browser.  In this case we want it in the “Pinball” tab, in the “Switch” category.  The name of the component will be “SwitchMatrix”

Screen Shot 2016-09-06 at 7.10.59 AM

For this component I want the user to be able to change the number of rows and columns.  I will do this by embedding the row and col digital input/output pins inside of the component.  And, the row,col pin components will be busses so that I can change the number.  First, you need to add a schematic to your component to hold the pins.

Screen Shot 2016-09-06 at 7.15.29 AM

I need to place a digital input pin (for the rows).  I select the number of pins to be 3 (this parameter will be changed by our customizer).  Also turn on the pull up resistors.

Screen Shot 2016-09-06 at 9.02.25 AM

Then I place a digital output pin for the columns.

Screen Shot 2016-09-06 at 9.06.10 AM

When I am done I will have a schematic that looks like this:

Screen Shot 2016-09-06 at 9.07.22 AM

Now I need to fix things up so that the user of the component can edit the number of pins.  To do this, I need to be able to edit the hidden parameter on the Cypress pins component which has the property of the number of pins in the bus.  To do this I first need to enable the secret menu which lets me edit the raw parameter.  This is on the Tools->options->design entry->component catalog menu.  You can see the “Enable Param Edit Views”.  By selecting this option you will be able to edit the raw parameter values on the components.

Screen Shot 2016-09-06 at 7.47.49 AM

Once you have enabled the menu you will be able to right click on the “Pins” tab of the component and show the “Show Expression View”

Screen Shot 2016-09-06 at 7.16.33 AM

Instead of the graphical interface to the component (shown above) you will have a list of the raw parameters (shown below)  Scroll down to “NumPins” and change it to the parameter that I put onto the symbol, “$NumRows”

Screen Shot 2016-09-06 at 7.16.50 AM

Lastly, do exactly the same thing for another pin for the Columns.  In the next post I will show and explain the source code for the component.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: A Switch Matrix

In the last several posts I talked in detail about reducing the number of pins required to drive a bunch of LEDs by putting them into a matrix.  In this post I am going to talk about doing exactly the same thing for switches.  For the pinball machine I would like to have at least 9 switches, so I will arrange them into a 3×3 matrix which will require only 6 pins.

Screen Shot 2016-08-15 at 8.20.14 AM

With a few minor differences, the system works the same as the LED matrix.  First you enable the pull-up resistors on the SWRow pins.  This forces a weak 5v onto the row pins.  Then you enable one column at a time by writing a “0” which forces 0v onto that column pin.  You also write a 1 onto the other column pins which forces 5V onto those pins.  You can see in the picture below that if you press the switch labeled S0,0 you will end up with 0V on the top input to the SWRow pin which will be read as 0.  With nothing else pressed you will end up with 1s being read on the other two row pins (because of the pullup resistors).

Picture-s1

So what are the diodes for?  If you don’t have the diodes then you have what is called the ghosting problem.  Ghosting means that when you press two switches at the same it will appear as a third different switch-meaning you will have a “ghost” press.   In the example diagram below I do exactly the same thing as before, except I also press Switch 0,1 and Switch 1,1.  Without the diodes this has the effect of propagating a 0 onto the input of Row 1 which makes it appear as if S1,0 is active even though it is not.

Picture-nodiodes

Here is the same picture with the diodes in.  You can see that the diode next to S0,1 and S1,1 are reversed biased and don’t conduct the 0.

Picture-diodes

To make the system I once again enlist my Lab Technician Nicholas and his friend Anna.

IMG_3012

And after some time and help and not too many burns:

img_3083 img_3082

Once I have the switch matrix test board setup, Ill build a project to test it.  The project is called “SwitchTestWiring”.  The firmware uses the systick timer to trigger a printout of the data every 200ms.  I then use the UART to read 0,1,2,3 to turn on the corresponding column.  Notice that I built a 3×3 test.

screen-shot-2016-09-08-at-8-02-59-am

In the next posts Ill build a component to run the matrix:

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Matrix LEDs Component

In the previous post I showed you how to build firmware to drive the LED matrix.  That firmware is in my TestMatrixBlinking project as led.h and led.c.  All that is pretty cool, but what I would really like is a component that is in a library, that I can configure the number of rows/columns and the update frequency–just like the other PSoC Components.  To do that I will go through the following steps

  1. Create a new library project
  2. Create a new component and symbol in the library
  3. Add the led.h to the header of the component
  4. Add the led.c to the implementation for the component
  5. Update the component properties to have the update frequency, number of rows, number columns etc.
  6. Add a reference the library in a test project
  7. Make the test project

First create a new project in the workspace.  In this case, I will build a library project.  A library project can’t be programmed into a board, but instead is used to hold components.

Screen Shot 2016-08-14 at 8.29.33 AM

Ill name the project “PinballComponents”

Screen Shot 2016-08-14 at 8.30.05 AM

Then I will create a new component.  To do this click on the components tab in the workspace explorer (in this picture you can see that I already added the new component)

Screen Shot 2016-08-14 at 2.16.55 PM

Next right click on the “PinballComponents” tab and select “Add Component Item”.  Then pick Symbol Wizard and name your Component “MatrixLed”.

Screen Shot 2016-08-14 at 8.31.02 AM

After you do that you will have “MatrixLed.cysym” in your library project.

Screen Shot 2016-08-14 at 2.19.43 PM

Now you need an API header file for the component.  To get this, right click MatrixLed and do “Add Component Item”.  Then select “API Header File” and tell it your header file will be MatrixLed.h

Screen Shot 2016-08-14 at 8.31.46 AM

Now copy the source code from led.h into MatrixLed.h. Replace “MatrixLed” with “`$INSTANCE_NAME`”.  When PSoC Creator builds your project it will replace the $INSTANCE_NAME with whatever you name your instance.

Screen Shot 2016-08-14 at 9.08.35 AM

The next step is to create the implementation.  To do this right click on MatrixLed and then select “Add Component Item”.  Pick “API C File” and name it MatrixLed.c

Screen Shot 2016-08-14 at 8.32.25 AM

Copy the source from “led.c” into the “MatrixLed.c”. Replace MatrixLed with “`$INSTANCE_NAME`” just like you did in the .h file.

Screen Shot 2016-08-14 at 9.13.23 AM

Now, right click on a blank space on the canvas in the symbol screen, then select “Properties”.  On the property “Catalog Placement” type in “Pinball/LED/LedMatrix”.  This will name a new tab for the component browser, a new subcategory and the name of the component.

Screen Shot 2016-08-14 at 8.45.42 AM

This is how it will appear in the Component Catalog.

Screen Shot 2016-08-14 at 2.45.40 PM

Now right click on the symbols canvas and select “Symbol Parameters”.

Screen Shot 2016-08-14 at 2.47.09 PM

The symbol parameters will show up in the component customizer when the user double clicks.  Add five parameters:

  • ColComponent as a string and a default value of “col” (this is the name of the pins component that you will use for the rows)
  • COLS as uint8 and a default of 4
  • ROWS as uint8 and a default of 4
  • RowComponent as a string and a default value of “row” (this is the name of the pins component that you will use for the columns)
  • Refresh as a uint8 with a default of 5 (this will set the #define for the Refresh rate)

Screen Shot 2016-08-14 at 10.24.27 AM

Next I realized that if I move the “NUMROWS” and “NUMCOLS” macro from the .c to the .h I will be able to use those macros in my main.c

Screen Shot 2016-08-14 at 10.25.47 AM

Then I modify the .c writes to the pins to have the names of the components

Screen Shot 2016-08-14 at 10.27.55 AM

The last step is to create a test project to make sure that everything works.  I create a new project called “TestBlinkingComponent”.  In order to access the Pinball Components you need to add a dependency to the new project.  To do this right click the new project in the workspace explorer and select “Dependencies…” then add “Pinball Components” to your list by clicking the “Components” checkbox.

Screen Shot 2016-08-14 at 8.39.57 AM

Now I make a schematic that looks like this.

Screen Shot 2016-08-14 at 10.29.16 AM

Because I moved the #defines to the .h file I can use them in the main project.  You can see that on line 21 where I reference MatrixLed_NUMROWS

Screen Shot 2016-08-14 at 10.30.32 AM

That is it for the component.  You can find it and the test project (TestLedBlinkingComponent) on github.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Matrix LEDs (Part 2)

In the previous post I talked about the design and test of a matrix of LEDs, specifically a 3×3 matrix.  The benefit of the matrix is that you use only sqrt(# LEDs) GPIO pins.  For my Pinball machine I am planning on using a 4×4 matrix.  There are two problems with this technique:

  1. You must limit the current through the LEDs so that you do not exceed the maximum current from the GPIO (which has the impact of dimming them)
  2. You can only select one row at a time (which has the impact of dimming them)

So how do you solve these problems?

Problem 1: Maximum Current

The worst case current occurs when you have one row selected and all 4 columns selected.  Here is the equivalent circuit:

Screen Shot 2016-08-13 at 9.04.12 AM

From the PSoC Datasheet I find that the maximum current in any GPIO is 25mA.  That means the maximum current through any of LED/Resistor branches must by less than one fourth (because I have 4 paths) of 25mA = 6.25mA.  We know that the forward voltage of the LED is about 3V.  In the previous post about LEDs I showed you that the worst case HighOutputImpedence is 180Ohms and the worst case LowOutputImpedence is 50Ohms.  Given those numbers, what is the value of the current limiting resistors?

R1 =  (5.5v – 3v – (180 Ohm*6.25mA) – (50Ohm * 6.25mA) ) / 6.25mA = 170 Ohms

Problem 2: Select One Row at a Time

How do you enable all of the LEDs to be turned on and still only select one row at a time?  The answer is that you need to time division multiplex the rows.

  1. Turn on row 0 for 10ms, turn on the correct columns
  2. Turn on row 1 for 10ms, turn on the correct columns
  3. Turn on row 2 for 10ms, turn on the correct columns
  4. Turn on row 3 for 10ms, turn on the correct columns
  5. Go back to the start

This means the LEDs will “blink” but they will blink so fast that you will not see them blinking.  The LEDs are being refreshed at 25Hz with a maximum duty cycle of 25%.  Before I build a general purpose component (the topic of the next post) I will make .h/.c files to implement the the timing scheme.  I start this process by copying the “TestMatrix” project from the previous post into a new project called “TestLedBlinking”.

What should the API for the LED system be?  What do I want the user of the component to be able to do?

  1. Start the system
  2. Turn on a specific LED
  3. Turn off a specific LED
  4. Toggle a specific LED
  5. Start an LED to blinking at some frequency
  6. Stop the blinking of a specific LED

To implement this I add a “.h” file called “led.h” to my project.  This file will contain the public interface to my LED system. On lines 11-18 I create the function prototypes for the interface.  But what are lines 5-9 about?  I want the LEDs in my system to have three possible states (ON,OFF and BLINK) but a “binary” variable is only two states.  I could use an integer with some convention about what 0,1,2,3,…. means with #defines.  But this is error prone as it is not type checked by the compiler.  To help avoid the errors I create a new Type of variable (using enum) called “MatrixLed_LedState” that has the three states that I am interested in.   The rest of the file contains the public interface to the component.

Screen Shot 2016-08-13 at 10.04.30 AM

After I finish the public interface I now need to build the implementation.  To do this I add “led.c” to my project with the c-functions and variables.

Lines 5-6 define the number of rows and columns in my design.  My comment says that you need to keep this less than 8 because the PSoC can only write to one 8-bit port at a time.  I use this to simplify the firmware.

Line 15 declares an array of uint8s that are the actual bits that need to be written to the columns to turn on/off the led in that row.

Line 17 declares a (row by column) sized array to keep track of the state of each LED.  It is of type “MatrixLed_LedState”

Lines 19-27 declare two arrays to keep track of the “counter” and “period” of the software PWM that I use to blink the LEDs.  (see the function MatrixLed_UpdateBlinking)

Screen Shot 2016-08-13 at 11.31.49 AM

The first function to build is the “Start” function.

Lines 120-128 just iterates through all of the row,columns and sets the bit mask to 0 (LEDs OFF) and the States to (OFF).

On lines 129+130 I start the SysTick timer.  I do not like using CyDelay to keep time.  When you use a CyDelay the processor does what is called a busy wait loop that looks like this:

for(int i=0;i<10000;i++); // 10000 is the number of times the CPU has to go through the loop for some amount of delay.  This is dependent on the CPU frequency

This “for” loop keeps the processor sitting in the same spot doing nothing but making heat.  This is not going to work in our system as we need other things to be going on simultaneously (like running switches, buzzers etc).   Instead of a busy wait loop I will use the built in timer in the ARM Cortex M0 core.  That timer is called “SysTick”.  In the Cypress PSoCs, this timer works when the CPU is Active or in Sleep.  By default, it “ticks” every millisecond.  Cypress provides you an API to turn on the timer called “CySysTickStart()”  How do you use it?  You register a callback function using the “CySysTickCallback()”  This function takes two arguments

  • The callback number (you can have up to 4 callbacks)
  • A function pointer to the function you want called back when the timer “ticks”

Screen Shot 2016-08-13 at 11.29.52 AM

The function MatrixLed_RunStateMachine is called by the SysTick interrupt.  This function is the basis of the whole system.  I want to every few milliseconds not every millisecond.  Specifically “every few” means every “MatrixLed_REFRESH” milliseconds.  I do this to save on CPU time.  In order to implement this idea I keep track of number of times the interrupt has been called using the static variable on line 108.  On line 112, when I reach an even number of “MatrixLed_REFRESH” I allow my processing routines to run.

Screen Shot 2016-08-14 at 7.11.29 AM

The other thing that I do in this function is toggle a pin high when I start the processing and then toggle it low when I finish.  I wanted to know how long the interrupt routine ran.  It is a very bad idea for interrupts to take a long time as it can impact other things going on in the system e.g. servicing the BLE.  By toggling the pin I can attach the test board to a logic analyzer and see how long the interrupt service routine takes.  Here is a screen shot from my Salea Logic Analyzer where you can see that the interrupt takes 10.5uS (worst case) runs every 3.986 ms which works out to a duty cycle less than 1% (so it shows 0%).  Why is it 4ms as earlier I said that you should do 10ms?  I tried 10ms, but I can see the LEDs flickering so I increased the update frequency.

Screen Shot 2016-08-13 at 1.15.42 PM

The next block of code drives the column and row pins to the right values.  On line 73 I declare a static variable currentRow which I use track which row needs to be driven this time.  Remember this function gets called every 10ms by the SysTick Interrupt.  Line 74 actually turns on the current row.  It uses the “<<” which is the c-operator also known as left shift.  That makes a value with a “1” in the position of the current row and a “0” in the other bits.  On line 75 I set the column bits to the correct value.  The system is “active low”, meaning you activate a column by driving it to ground.  After all of the updates are done you setup for the next time on line 76 by moving to the next row.

The only other interesting thing about this function is that I declared it with the keyword inline.  This keyword tells the compiler to NOT call it as a function but to put it directly in the assembly language at the place where it is called i.e. to embed it there.  Using inline will save CPU cycles as you don’t have to save a bunch of registers onto the stack, jump, pull a bunch of registers and jump back.  The only downside is that you will get multiple copies of the same function (wasting space).

Screen Shot 2016-08-14 at 7.27.14 AM

The next function handles the blinking.  The blinking is a simple software PWM.  The PWM counts from the “Period” down to 0.  When it hits 0, it toggles the LED, then resets the counter back to the Period.

This function when called, iterates through the matrix of LEDs (using the two nested for-loops), if an LED is in the blinking state (line 89) then do the down count and toggle the LED if needed.

Screen Shot 2016-08-14 at 7.36.28 AM

The MatrixLed_Blink function configures the state and period.  The period is set by:

Period = 1000/frequency/2/MatrixLed_REFRESH

Screen Shot 2016-08-14 at 7.42.22 AM

The last three functions are just helper functions to set the bits in the “MatrixLed_ledRows” for the column values.

Screen Shot 2016-08-14 at 7.41.59 AM

In the next post Ill show you how to turn all of this into a component.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply

Pinball: Matrix LEDs (Part 1)

In the previous post I talked in detail about driving LEDs using the PSoC4 BLE GPIOs.  The basic problem that I have now is that I want to drive way more LEDs than I have available GPIO pins.  Using one GPIO per LED means that I am only able to drive 8 LEDs with the 8 pins that I have reserved.  But I want to do 16 not 8.  So now what?  To solve this, I configure the LEDs into the Matrix.  In the schematic below you can see an example 3×3 test matrix.  It uses 6 pins and is able to drive 9 LEDs.

So how does it work?  Simple.  Write a 1 onto the row you want to enable then write a 0 onto the other rows.  Next write a 0 onto the column you want to enable and a 1 onto the other columns.  For example, if I drive 010 onto the “row” pins and 101 onto the column pins then the LED I have labeled 1,1 will turn on.  With this scheme the row pins are used to drive the “power” and the column pins are used to drive the “ground”.

Screen Shot 2016-08-11 at 7.35.05 AM

Then I get the lab assistant a.k.a. 12 year old son Nicholas to build up a test board.

IMG_3008IMG_2989

I need a little bit of firmware to turn on each LED one by one.

  • Lines 17-19: iterate through the three rows/columns
  • Line 23: write the correct pattern to the row driver (001,010,100)
  • Line 21-22: print the current row column to the UART
  • Line 24: write the correct pattern to the column driver (110,101,011)

Screen Shot 2016-08-11 at 1.14.49 PM

After that everything seems to work… you can see how bright the LEDs are in the movie below.

In the next post I will show you how to Time Division Multiplex the LEDs and explain what the problem is with that scheme.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply