For those who asked how to add hardware and software to their
Wise Clock 3 or
4, here is a step-by-step recipe, using the example of a digital vu-meter. The hardware itself is
nothing new, based on the
MSGEQ7 "graphic equalizer display filter" chip. The minor challenge is adding the multi-band vu-meter application to the existing
Wise Clock 3/4 software.
Step 1.
First make sure that the new hardware works on its own. Connect it to an Arduino and test it with a sketch that performs the desired functionality. This sketch will be the base code for your new
Wise Clock 4 "app".
In my example, I assembled the circuit shown below, where the MSGEQ7 and the 3216 display are connected to an old seeeduino. The 3216 display is connected to the same digital pins used in
Wise Clock 4 (D12, D13, D14, D15). The MSGEQ7 chip uses analog pin A2 and digital pins D2 and D3 (these will need to be later adapted for
Wise Clock 4).
The little green "appendix" connected to the MSGEQ7 board is the
IN-ZX-Sound microphone amplifier, which could be replaced with the cheaper and probably better
version from Adafruit.
The working vu-meter sketch (compiled and tested in Arduino 1.0) can be found
here.
Step 2.
Re-wire the hardware to the
Wise Clock 3/4 board, using digital and/or analog pins that are not already taken, like D18, D19 and A0-A7 (check
schematic here).
Note: Some "already taken" pins could be re-assigned, but the original functionality that they provide will be lost. For example, you could re-use D20 and D21, which are currently involved in serial communication with the BT module (through SoftwareSerial library, look for USE_SOFTWARE_SERIAL macro in WiseClock.cpp), but then communication with the module will be disabled.
In the example, since the 3216 display is already connected (D12-D15), I only had to find two available digital pins (the only choice being D18 and D19) and one analog pin (A0) to connect the MSGEQ7 chip to the ATmega644/1284.
After soldering the 5 wires (3 signal, Vcc and GND), the hacked
WC4 board looks like this. (Note that the yellow wire in the photo is left unconnected.)
Step 3.
Make sure that the code that worked with Arduino (in
Step 1) still works with the
Wise Clock 4 board (target board "Sanguino" or "Sanguino with Atmega1284/16MHz" in Arduino IDE), after the hardware and software changes.
In my example, because I am using D18 and D19 (also used by JTAG), I had to disable JTAG in the code, using these lines:
uint8_t tmp = 1<<JTD;
MCUCR = tmp;
MCUCR = tmp;
This is the
Wise Clock 4 with the display and the attached VU-meter board:
Step 4.
Now we focus completely on the software. To add a new app to the existing
Wise Clock sketch, start with creating 2 new files (.h and .cpp) for the new app class. One easy way, for example, is to copy the files
AppLife.h and
AppLife.cpp and rename those copies
AppVu.h and
AppVu.cpp, then delete the implementations of the 2 functions (
init() and
run()) . After updating their content, the 2 new files should look like the ones below.
// file AppVu.h
#ifndef _APP_VU_H_
#define _APP_VU_H_
#include "Arduino.h"
class CAppVu
{
public:
void init();
int16_t run();
};
extern CAppVu appVu;
#endif // _APP_VU_H_
// file AppVu.cpp
#include "AppVu.h"
#include "HT1632.h"
void CAppVu::init()
{
// todo:
}
int16_t CAppVu::run()
{
// todo:
}
CAppVu appVu;
Step 5.
Modify
WiseClock.cpp to include the new header, add new menu item ("VU"), reference the global single instance of this class (named
appVu in this case) etc. Basically, add the following lines (in the appropriate places):
#include "AppVu.h"
...
// add to enum of menu item indexes
#ifdef _APP_VU_H_
MENU_VU,
#endif
...
// add the menu item display string
#ifdef _APP_VU_H_
const char menu_str_vu[] PROGMEM = "VU";
#endif
...
// add to const char * menu[] PROGMEM = {...
#ifdef _APP_VU_H_
menu_str_vu,
#endif
...
// in WiseClock::processButtonSet()
#ifdef _APP_VU_H_
case MENU_VU:
crtApp = APP_VU;
appVu.init();
--item;
isMenuActive = false;
break;
#endif
...
// in WiseClock::runCrtApp()
#ifdef _APP_VU_H_
case APP_VU:
ms = appVu.run();
break;
#endif
In file
WiseClock.h add the name of the new app (APP_VU) at the end of the enum:
// names of the possible "applications";
enum { APP_QUOTE, APP_UTC, APP_BIG, APP_LIFE, APP_DEMO, APP_PONG, APP_PACMAN, APP_LIVED, APP_SCORE, APP_STOPW, APP_CNT_DOWN, APP_WORDS, APP_MSG, APP_STATS, APP_TCLOK, APP_TIX, APP_LINES, APP_SUN, APP_ANIM, APP_LOG_CLEAR, APP_TMP, APP_NEWSD, APP_VU };
After all these changes are done, make sure that the Wise Clock sketch still compiles (even without the functions CAppVu::init() and CAppVu::run() implemented).
Step 6.
Implement the functions
init() and
run() of the new class (
CAppVu::init() and
CAppVu::run() in my example). The code for
init() should be copied from the function
setup() of the prototype sketch (in
Step 1).
void CAppVu::init()
{
// disable JTAG;
uint8_t tmp = 1<<JTD;
MCUCR = tmp;
MCUCR = tmp;
// MSGEQ7;
pinMode(analogPin, INPUT);
pinMode(strobePin, OUTPUT);
pinMode(resetPin, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, HIGH);
clearDisplay();
}
The code for
run() comes from the
loop() function in the prototype sketch of
Step 1.
// show 2-columns bars for each of the 7 channels;
int16_t CAppVu::run()
{
clearDisplay();
digitalWrite(resetPin, HIGH);
digitalWrite(resetPin, LOW);
for (int i = 0; i < 7; i++)
{
digitalWrite(strobePin, LOW);
delayMicroseconds(30); // allow output to settle;
spectrumValue[i] = analogRead(analogPin);
digitalWrite(strobePin, HIGH);
// try to eliminate some noise;
if (spectrumValue[i] < 100)
spectrumValue[i] = 0;
int x = i*5;
int vu = spectrumValue[i]/64;
if (vu <= 8)
{
ht1632_line(x, 15, x, 15-vu, GREEN);
ht1632_line(x+1, 15, x+1, 15-vu, GREEN);
}
else if (vu <= 12)
{
ht1632_line(x, 15, x, 8, GREEN);
ht1632_line(x+1, 15, x+1, 8, GREEN);
ht1632_line(x, 7, x, 15-vu, ORANGE);
ht1632_line(x+1, 7, x+1, 15-vu, ORANGE);
}
else
{
ht1632_line(x, 15, x, 8, GREEN);
ht1632_line(x+1, 15, x+1, 8, GREEN);
ht1632_line(x, 7, x, 4, ORANGE);
ht1632_line(x+1,7, x+1, 4, ORANGE);
ht1632_line(x, 3, x, 16-vu, RED);
ht1632_line(x+1,3, x+1, 16-vu, RED);
}
}
}
Note that the CAppVu::run() uses a new display function ht1632_line(...), which needs to be added to HT1632.h and cpp.
Step 7.
Compile, upload and test. Then improve, extend, publish and brag about it :)
Homework
Add graphic effects (e.g. display like a 6-inflection point graph), selectable from menu (follow example of the UTC app).