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

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

The Creek: Creek Server 1.2

In the previous post, I talked about two problems that I had discovered in my system.  I addressed first one,  a serious bug in the data collection, last time.  In this post Ill address the slow performance of the website.  A common way to solve a performance problem is with a cache.  Instead of running the web page charts in real time, I will create them automatically every couple of minutes, then serve up a cached version.   In some ways this kind of sucks.  If I had known that I was going to go this way then there would have been 0 need of Tomcat and the Java Server Pages.  Oh well.

I start this process by copying the CreekHistory java object into the “getCreek” part of my project.  I then modify the main batch Java program, called “CreekServer” to understand the CreekHistory object.

Screen Shot 2016-05-08 at 11.19.48 AM

Then I add a new function “createHtml” to the CreekHistory object.  This function creates the webpage with the current information on it.  Basically

  1. A table of the last three hours [line 221-235]
  2. Link to the current chart [line 237]
  3. Link to the floods charts [line 237/238]

Screen Shot 2016-05-08 at 11.26.31 AM

I then add the “Current” command to the “runi2c” batch program.

Screen Shot 2016-05-08 at 11.39.43 AM

This program is run every 2 minutes by the crontab on the Raspberry Pi.  I picked 2 minutes because that is a good bit longer than each job takes to run in total.   Notice that I check to see if the jobs are already running and quit the “runi2c” job if the chart creation process is already going on.

At this point I have (at least) several things which are ugly

  1. I don’t have a good back up system
  2. I duplicate the “CreekHistory” object in the JSP as well as the “getCreek”
  3. I duplicate the “readProperties” method into a bunch of different objects
  4. I have 5Vs (I think) on the I2C pins of the Raspberry Pi, which I don’t understand why this isn’t a problem
  5. I need to get the PSoC4 Bootloader Host going on the Raspberry Pi

Index Description
The Creek: IOT for the Elkhorn Creek Introduction
The Creek: Solution Architecture 1.0 Overall architecture
The Creek: Creek Board 1.1 Eagle layout of the board
The Creek: Creek Board 1.0 – RCCA A discussion of the errors in the 1.0 board
The Creek: CYPI, a Raspberry Pi to Arduino Bridge PSoC4 <--> Raspberry Pi Bridge Board
The Creek: PSoC4 Creator Schematic and Firmware Firmware to interface with the temperature and pressure sensors
The Creek: Testing the Firmware Using tools to verify that the PSoC 4 Firmware is working correctly
The Creek: Testing the Bootloader Make sure that you can load new firmware into the PSoC
The Creek: Software Architecture All of the Raspberry Pi software connections
The Creek: Install MySql Instruction to configure MySql
The Creek: Install Tomcat Instruction to configure Tomcat JSP Server
The Creek: Data Collection Java (Part 1) The Java program that reads the I2C and saves it in the database
The Creek: Data Collection Java (Part 2) The Java program that reads the I2C and saves it in the database
The Creek: Create the Chart with JFreeChart Using open source Java charting software to create plots of the Creek Depth
The Creek: Flood Event Data Processor A batch program to create analyze the database and create a table of flood events
The Creek: Flood Event Web Page A batch program to create the flood event web page
The Creek: Creek Server 1.1 Updates to all of the back off server programs to integrate charts
The Creek: JSP Web Page for www.elkhorn-creek.org The JSP program to make the table and display the website
The Creek: Raspberry Pi Clock Stretching Sorting out a bug in the system having to do with the Broadcomm Raspberry Pi Master not functioning well with clock stretching
The Creek: Creek Server 1.2 Caching the web pages to make them faster

 

WICED WiFI

Last week I had the supreme privilege of hosting the WICED WiFI + Bluetooth + Zigbee software team at my office in Kentucky. This included the overall manager for WICED software (a truly remarkable guy), the engineering managers for WiFI and Bluetooth, the head of applications for WICED as well as a bunch of the firmware guys.  It occurred to me during the week that the people joining Cypress was the best part of the Broadcomm IOT acquisition.  And that is saying something as I really like the products.  Also at the summit were all of the software engineering leaders for PSoC (who I have worked with closely all of my career).  Needless to say, it was a bunch of badass developers.

The purpose of the meeting was to introduce the PSoC team to WICED and then talk about the future roadmap for those products.  Obviously I can’t talk to much about the 2nd part… well actually the only thing I can say is that it will be amazing as we will be able to offer PSoC with the power of WICED.

What I can talk about is the first part.  So, I thought that I would show you one of the things that we did with WICED.  First of all, WICED (Wireless Internet Connectivity for Embedded Devices) is the brand name that Cypress uses to describe all of the WiFi, Zigbee and Bluetooth chips and modules that were acquired from Broadcom/Avago.  The other thing we call WICED is the WICED SDK which is used to mean Eclipse plus all of the tools (programer, plugins etc) plus the software library that is used to build products using the WICED chips and modules.

In the world of programming the first example is always “hello world”.  In the world of MCUs the first example is always “blinking led”.  It turns out that the first example in WiFi is “scan” to show that you can see all of the WiFi networks around you.   The purpose of all of these examples is to prove that all of the tools can do their thing.

To start with they gave me this devkit, the BCM94343WWCD1_1  IMG_3049

The first thing to do is install WICED 3.7.  When you start WICED you will see a screen like this:

Screen Shot 2016-08-22 at 8.22.06 AM

For the purposes of the first design there are two important things to see on this screen.  First on the left side is the project explorer.  It has all of the guts of WICED.  As part of the installation we provide you a bunch of “apps”.  These apps range from simple examples (in the snip folder) to full fledged production quality applications (in the demo folder)

  • demo – full fledged applications
  • snip – short example projects
  • test – tools for debugging and testing wifi
  • waf – WICED Application Framework support (like an OTA Bootloader)
  • wwd – low level driver examples

Screen Shot 2016-08-22 at 8.27.04 AM

The example that I want to build is “scan”  specifically “scan.c”.  That can be found in the apps/snip/scan folder.  In this screenshot you can see that I opened “scan.c”

Screen Shot 2016-08-22 at 8.43.49 AM

The next thing that you need to do is build a “make target”.  The WICED team built a makefile that can seemingly do everything.  The makefile uses the name of the make target to setup all of the options required to do the make.  If you look on the right side of the screen you can see the currently existing targets:

Screen Shot 2016-08-22 at 8.24.40 AM

The easiest way to make a new target is to copy/paste a currently existing target.  Then you can right click on the new target and edit it to get things setup correctly.  The target name defines:

  • snip – the directory
  • scan – the subdirectory will the files (scan.c and scan.mk)
  • BCM94343WWCD1 – the name of the devkit (you can see it on the picture of the devkit)
  • download run – instructions to go ahead a boatload and start the app running

Screen Shot 2016-08-22 at 11.32.06 AM

Next, I plug in the devkit.  When it attachs, the devkit will enumerate as two USB devices

  • WICED USB JTAG Port
  • A serial port (in this case on COM12)

Screen Shot 2016-08-22 at 11.29.45 AM

After I plug in the kit I run Putty and attach to COM12 at 115200 baud

Screen Shot 2016-08-22 at 11.36.32 AM

And finally, double click the make target to build, download and run.  After it starts, the Putty screen fills up with all of the WiFI networks that are around me.

Screen Shot 2016-08-22 at 11.30.39 AM

All of that was pretty easy to get going.  Next lets see if I can actually do something.  Last week I showed the guys the Elkhorn Creek Water Level monitoring project and I told them that by the end of this week I would put one of their devkits into that system, so the next several posts will be about that process. (I hope)

The Creek: Web Pages with Java Server Pages (JSP)

The last piece in the Elkhorn Creek IOT puzzle are the webpages that let you view the creek data on the internet.  There are two pages, one with a table of the data and a chart and the other a dump CSV file of the database.  When it came time to work on this post, I realized that I had little memory of the evils deeds I had originally done to make the JSP pages work.  As I sorted through the code that was existing on the current production Raspberry Pi environment, all I could see was an undocumented mess.

Making dynamic web pages is ugly business.  As best I can tell, there is no clean way do this job (though I am planning on showing some ways to make it better in future posts).  A JSP is an interleaved mashup of HTML and Java.  To make a JSP, you create a file with sections of both languages separated by markers.   In the following example you can see an example that rolls two dice (generates a random number between 1-6).  The sections of code that are Java are marked with a “<%” and a “%>”.

<html>
<head><title>Roll the dice</title></head>
<body>
<%
int die1 = (int)(Math.random() * 6 + 0.5);
int die2 = (int)(Math.random() * 6 + 0.5);
%>
<h2> Die1 = <%= die1 %></h2>
<h2> Die2 = <%= die2 %></h2>

<a href=”<%= request.getRequestURI() %>”><h3>Try Again</h3></a>
</body>
</html>

When a web request is made, the Tomcat JSP Webserver takes the page (in JSP format)

  1. Converts it to Java (turns raw HTMLs into java commands e.g. “<html>” turns into “out.println(“<html>”);”
  2. Runs the compiler
  3. Executes the java program and pipes the output back to your web browser

To makes things go faster Tomcat will cache the output of 1+2 and only rerun it if something has changed.

Since I last worked on this system there is one thing that had greatly improved.  Specifically, this time I knew about Netbeans which is the Sun Microsystems IDE for editing Java.  Netbeans is cool for this project because:

  • It knows about Java (so it knows how to edit, highlight, search, refactor, syntax check etc)
  • It knows about JSP (so it knows how to edit…)
  • It knows how to edit Java Properties files
  • It has a JSP web server (GlassFish) integrated into the tool.  This allowed me to debug the web pages on my Mac (instead of on the RPi)
  • It knows how to make “war” files (the file format that you use to deploy a JSP web application)

The Netbeans project navigator lets you look at (and into) all of the files that are part of the JSP Web Application.  In the screenshot below you can see the organization of my project.  It has

  • A classes folder which will contain the compiled java classes.  It can also hold a “properties” file.  In this case I have a properties file called “config.properties” which contains the URL, User and Password for the mysql database
  • basic.jsp: The JSP file which displays the table and graph
  • index.html: a file which just loads the basic.jsp
  • CreekHistory.java: A java class to interact with the MySql Database.  This is essentially the “Model” of the MVC
  • A libraries folder with mysql-connector-java-5.1.6-bin.jar: the mysql library to connect to the database

Screen Shot 2016-05-03 at 7.13.26 AM

I like to use the Model View Controller (MVC) design paradigm of user interface programming.  In this methodology the model represents the data.  It knows nothing about user interfaces, how to create them, how to display them.  It is completely agnostic about GUI.  The view is a mechanism to display data. In this JSP web application, the view is just the raw html that is displayed on the web.  The last piece is the controller (aka the view controller).  It takes data out of the model and puts it into the view.  Here is a nice picture from Apples website (but if you google you will find lots of discussion about MVC programming)

model_view_controller_2x

The first thing that I created was Java class called CreekHistory.java.  This class has the responsibility to read the last 4 hours of depth and temperature data from the MySql database and put it into 15 minute buckets (using linear interpolation), and store the results into an array for easy retrieval by the controller.

In the first block of code (lines 29-31) I declare a few private variable that hold information out of the properties file about the database connection. The I declare a bunch of public variables which are the data interface to the model.

  • depth[] + temperature[] arrays of doubles that contain the depth and temperature in 15 minute buckets
  • depthDelta[] and temperatureDelta[] doubles that contain the change in depth and temperature since the start aka [0]
  • startTime a timestamp of the first datapoint (from the MySql database)

In the next clock of code (lines 43-46) I declare some constants (so that I don’t have magic numbers in my code).

On line 48 I declare a reference to a JspWriter.  This reference will allow me to print debugging information to the HTML output.  This is a clear violation of the MVC so I only use it for printing debugging information as it is a serious PITA to debug JSP code.

And finally the constructor which calls the function to read the properties file and then initialize the arrays.

Screen Shot 2016-05-04 at 6.25.48 AM

In the next section of code I have three helper functions.

The first function “interpolate” just performs a linear interpolation between two datapoints given known timestamps.

The “cToF” function just converts the a temperature from the bogus Centigrade units to useable Fahrenheit.

The last function, “readProperties” finds the config.properties file and reads the values into the global Properties class.  The only magic in this function occurs on lines 194-195 where it uses the ClassLoader object to search through the “classes” directory to find the file with the properties.

 

Screen Shot 2016-05-04 at 6.32.46 AM

The last function is “loadData” which has two sections.  The first section sets up and executes the MySql query to get the current Elkhorn Creek data.

Screen Shot 2016-05-04 at 6.40.44 AM

Once it has the data, it iterates through the data from the MySql database to find the datapoints that bracket the 15 minute buckets, then interpolates the results, then store it in the array.

Screen Shot 2016-05-04 at 6.51.08 AM

Finally the last part of the web server is the JSP page which outputs the actual HTML.

Lines 1-2 load two Java classes which I use on other sections of the page.  Specifically the Timestamp class which I use to do Time math, and the CreekHistory class which is the “model”

Lines 15-18 initialize the CreekHistory model object and tell it to load its data.  Notice on line 16 if I set the CreekHistory “out” public variable then it will put out debugging information.

Lines 24-37 just spit out an HTML table of the data from the CreekHistory model.

Screen Shot 2016-05-04 at 7.04.07 AM

That is all there is to it.  As with all of the code on this website you can get it from github.

Index Description
The Creek: IOT for the Elkhorn Creek Introduction
The Creek: Solution Architecture 1.0 Overall architecture
The Creek: Creek Board 1.1 Eagle layout of the board
The Creek: Creek Board 1.0 – RCCA A discussion of the errors in the 1.0 board
The Creek: CYPI, a Raspberry Pi to Arduino Bridge PSoC4 <--> Raspberry Pi Bridge Board
The Creek: PSoC4 Creator Schematic and Firmware Firmware to interface with the temperature and pressure sensors
The Creek: Testing the Firmware Using tools to verify that the PSoC 4 Firmware is working correctly
The Creek: Testing the Bootloader Make sure that you can load new firmware into the PSoC
The Creek: Software Architecture All of the Raspberry Pi software connections
The Creek: Install MySql Instruction to configure MySql
The Creek: Install Tomcat Instruction to configure Tomcat JSP Server
The Creek: Data Collection Java (Part 1) The Java program that reads the I2C and saves it in the database
The Creek: Data Collection Java (Part 2) The Java program that reads the I2C and saves it in the database
The Creek: Create the Chart with JFreeChart Using open source Java charting software to create plots of the Creek Depth
The Creek: Flood Event Data Processor A batch program to create analyze the database and create a table of flood events
The Creek: Flood Event Web Page A batch program to create the flood event web page
The Creek: Creek Server 1.1 Updates to all of the back off server programs to integrate charts
The Creek: JSP Web Page for www.elkhorn-creek.org The JSP program to make the table and display the website
The Creek: Raspberry Pi Clock Stretching Sorting out a bug in the system having to do with the Broadcomm Raspberry Pi Master not functioning well with clock stretching
The Creek: Creek Server 1.2 Caching the web pages to make them faster