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

Pinball: Lotsa Blinking LEDs

When I saw the Pinball machine prototype I knew that we needed lots of blinking LEDs.  After all everybody needs lotsa blinking lights.  However, I also knew that I wanted to keep the cost down.  Moreover, I am planning on using a PSoC that has 25 GPIO pins so I am somewhat pin limited.  I started by looking around a little bit on Arrow’s website for a bright blue LED and I found this one.  It is a pretty typical LED with the following characteristics:

  • The Lens is 5MM (Physically it should fit well into the game)
  • Blue (OK.. I like blue)
  • The average forward current IAF=20mA (OK that is very common)
  • The typical forward voltage VF=3.5V (OK that is very common)
  • The luminous intensity is 7000mcd (wow that is really bright.  mcd = millicandelas which is a unit of brightness)

What do these metrics mean?  First, they want you to operate the LED at 20mA of current and 3.5V of “forward voltage”.  The power supply in my system is going to be 5V, but the LED wants to be 3.5.V?  In order to get the correct voltage across the LED I will build a circuit that looks like this:

Screen Shot 2016-08-10 at 6.33.26 AM

You can see that the voltage across the resistor will be 5v-3.5 = 1.5V.  So what size does the resistor need to be to make the current be 20mA?  From Ohms Law (V=IR or R=V/I) you need the R=1.5V/20mA=75Ohms.

The next thing that I did was build a circuit on my bench to test and see how things were working.  In the box of parts in my lab I had an LED with a forward voltage of 3V so I calculate that my resistor needed to be 100Ohms.

When I measure (using my Fluke meter) I find out that the parameters of the system are actually:

  • Vcc = 4.7 (instead of 5V)
  • The LED VF=2.97 (instead of 3.0)
  • The R=98.8 Ohms (instead of 100)
  • The IAF = 17.5mA (instead of 20)

OK.  All of that makes sense.  The next step in building the blinking LEDs is to drive the same circuit with a PSoC pin just to make sure everything is still OK.  To do this I build a schematic in PSoC Creator that looks like this:

Screen Shot 2016-08-10 at 6.58.23 AM

And I configure the GPIO like this:

  • Select “Initial drive state: High” which means that the pin will start at Vcc
  • Select “External terminal” so that I can draw the whole circuit on the outside of the PSoC using the annotation components

Screen Shot 2016-08-10 at 6.57.48 AM

When I program the project and measure the output I get:

  • VF=2.9V
  • VR=1.35
  • IAF=13.7mA = 1.35V/98.8Ohm

These results are confusing because VF+VR=4.25V yet when I measured the power supply it is 4.9V.  Where did the other 650mV go?  When I first took the measurement I was worried for a moment that I had drawn to much current out of the PSoC and something was bad.  But there was no smoke so that didn’t explain anything.  Still confused as I was drawing only 13mA and the chip is capable of delivering 25mA on a GPIO pin.  Here is a snap from the PSoC data sheet where you can see SID4 is 25mA.

Screen Shot 2016-08-10 at 7.14.07 AM

The bottom line is 13mA < 25mA so if to much current isn’t the problem then what it is?  The answer is that the output impedance of the chip is not 0.   What is “output impedance”?  Inside of the chip there is an PMOS transistor that is used to drive the “1” (or an NMOS for “0”) onto the output pin of the chip (the circuit on the left side of the picture).  When this transistor is On and you are driving a 1 onto the output pin, a good model for the on PMOS transistor is a resistor (the equivalent circuit on the right)

Screen Shot 2016-08-10 at 8.34.48 AM

In the case of my circuit the output impedance (from Ohms Law) must be

R = 0.65v / 13.7mA = 47.7 Ohms

OK that is curious.  The next question is what is the output impedance of the pulldown transistor?  To find the answer I build the same circuit except using a pulldown in the PSoC and powering it with the VCC directly.  In fact I built all 4 combinations (power from the VCC, ground from the ground, power from the chip and ground from the chip).

Screen Shot 2016-08-11 at 6.14.20 AM

Here is the table of results.

Configuration V(VCC-LED) VF VR V(R-GND) Total Act VCC-GND IAF Rhigh Rlow
Only Pullup 0.65 2.90 1.35 0 4.91 4.9 13.7 47.7 0
Pullup and Pulldown 0.62 2.88 1.26 0.13 4.90 4.9 12.8 48.9 10.2
Pulldown Only 0 2.95 1.60 0.17 4.71 4.7 16.2 0 10.5
No PSoC 0 2.97 1.73 0 4.7 4.7 17.5 0 0

Does all of this make sense?  What does the data sheet say?  It turns out that the data sheet does not specify the output impedance.  Instead, it give the worst case output voltage for a high and a low AT a given current and VCC spec.  From the spec SID59 (data sheet below) you can see that the worst case Voh is -0.6v at Ioh=4mA and 3V VDD.  That spec says that IF you power the chip at 3V AND you draw 4mA out, then the “high” or “1” output will be NO LESS than 2.4V.  This is another way of saying that the output impedance of that condition is no worse than 0.6V/4mA = 150 ohms.

Screen Shot 2016-08-10 at 7.15.12 AM

Why is Voh specified as a worst case current/voltage combination?  The basic answer is the output buffer has a transistor, actually several transistors, driving the output.  The actual V/I characteristic of a transistor is not as simple as just a resistor and it depends on the voltage of the gate, source, and drain.  But this would be too much complexity to publish and is unneeded as GPIOs are used to drive logic signals outside of the chip.  In the digital output situation you just need to insure that the HIGH output has a high enough voltage to be a logic 1 and that a LOW output is low enough to be a logic 0.  In a normal system, logic signals do not require very much current-generally <1mA so 4mA is a worst case scenario.

In the next post I will talk in detail about how to turn 8 GPIO Pins into 16 outputs.

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: Newton’s Attic Pinball

One of the most important Cypress distributors is Arrow Electronics.  Recently, I have been talking with our inside people about using Arrow to supply chips for use in a Maker style PSoC project.  Moreover, I will be speaking at Maker Faire NYC in October, and I would like to have a Maker project to show there.  But what project?

In the (incomplete) series about Physics Lab I introduced you to my friend Billy and his non-profit company Newton’s Attic.  He teaches Physics and Engineering classes to Middle School and High School kids. In one of the classes (called Pinball Wizard) taught at Newton’s Attic the kids build a Pinball machine which they take home.  Here are a couple of pictures:

0731161220 0731161219

The current focus of the class is on the creative and mechanical side of building the pinball machine.  When I saw the prototype, I immediately thought that I should build an electronics toolkit for easy installation into the machines.  So that is what I am going to do.  To make matters more interesting I am going to finish it and post about it most every day before Maker Faire NYC on 10/1.

The big picture requirements are:

  1. Easy for the kids to install
  2. Low cost (<$30)
  3. Configurable over BLE via a smart phone
  4. No programming required
  5. Small (about the size of a deck of cards)
  6. Glitzy (lots of blinking lights and beeping buzzers)

With all of that in mind I am currently planning on ~$40 (I’m currently over my goal)

  1. A PSoC4 BLE as the central processor $12 with 25 IO Pins
  2. An I2C based LCD $8 and 2 Pins
  3. 2 Capsense Buttons $0 and 2 Pins
  4. 2 Buzzers (One for music and one for beeping) $2 and 2 Pins
  5. 16 LEDs in a 4×4 matrix $2.5 and 8 Pins
  6. 9 Switches in a 3×3 matrix $8 and 6 Pins
  7. 1 Printed Circuit Board $5
  8. 5V wall wart $5
  9. 2 Small DC Motors $2 and 4 pins

My plan is to build an iOS and an Android App that will allow you to configure the electronics.

  1. Configure beeps (frequency and duration)
  2. Configure the switches to trigger beeps
  3. Configure the switches to count points
  4. Configure the switches to trigger LEDs
  5. Configure patterns of LEDs (flashing and sequence)
  6. Configure songs (notes, duration, tempo)
  7. Set the triggers and speed for the motors

For the next month I am going to (try) to post each day my progress towards finishing the Pinball machine.

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