Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 6:012504bfe3e3
- Parent:
- 5:8ae5aca33233
--- a/main.cpp Sat Dec 12 02:59:41 2015 +0000
+++ b/main.cpp Sun Dec 13 08:25:34 2015 +0000
@@ -1,7 +1,7 @@
/************************************************************************
-* Authors: Alec Selfridge/Dylan Smith
-* Date: 12/4/2015
-* Rev: 1.4
+* Authors: Riley Barnard, Kamyar Izat, Alec Selfridge, Dylan Smith
+* Date: 12/12/2015
+* Rev: 1.6
* Project: RTOS Light Animations
* Notes: The z-axis of the accelerometer is used to calculate the
* "effective" angle that the board is tilted. First, the Z data
@@ -15,7 +15,14 @@
* and vice versa.
* A 5-axis joystick is used to mix R, G, and B values to create
* a custom color. The RGB LED is controled via PWM with a value
-* of 1.0 indicating "off" and vice versa.
+* of 1.0 indicating "off" and vice versa.
+* The joystick itself is off-site on a slave board connected via
+* SPI. Each component is requested and applied when all 3 are
+* received.
+* SYSTEM:
+* Threads: 2
+* Timers: 2
+* ISRs: 1
*
************************************************************************/
@@ -28,21 +35,27 @@
#define X 0.0299
#define C 0.1883
-#define UART0 0x4000C000
-#define UART0CTL (UART0 + 0x30)
+#define R_CODE 1
+#define G_CODE 2
+#define B_CODE 3
/*
-**************************
- Display Functions
-**************************
+******************************************************
+ Display Functions
+******************************************************
*/
void displayBanner();
-void newline();
-
+void eol();
+void testLED(void);
+void testRGB(void);
+void LEDPush(void const *args);
+void RGBupdate(void const *args);
+void RGBPush(void);
+unsigned char mapLEDS(double v);
/*
-**************************
- Utility Functions
-**************************
+******************************************************
+ Utility Functions
+******************************************************
*/
void SerialInit(void);
void AccInit(void);
@@ -51,20 +64,14 @@
void accFeed(void);
void sampleAcc(int period, int32_t data[3]);
double getAngle(void);
-unsigned char mapLEDS(double v);
-void LEDPush(void const *args);
-void RGBpicker(void const *args);
-void testLED(void);
-void testRGB(void);
int testSlave(void);
void checkSSEL_isr(void);
-void unpackRGB (void);
+void unpackRGB(int tempR, int tempG, int tempB);
void packRGB (int R, int G, int B);
-void RGBconvert(void const *args);
/*
-**************************
- Global Data
-**************************
+******************************************************
+ Global Data
+******************************************************
*/
const char banner[37] = "Serial Comm Established with LPC4088";
// x, y, z
@@ -74,31 +81,28 @@
int32_t accData[20][20][20] = {};
// holds calibration offsets
int32_t accCal[3] = {};
-// holds last acc value
-int32_t acc_old = 0;
+// status register for R, G, and B
+bool sentStatus[3] = {};
// holds most recent, adjusted, acc value
double acc_adj = 0.0;
// a value representing what's shown on the LEDs
uint8_t LEDvals = 0;
-// tracker of how many times the joystick was used
-uint8_t tick = 0;
// red value of RGB
float r = 0;
// green value of RGB
float g = 0;
// blue value of RGB
float b = 0;
-
-int RGB = 0;
-
-int RGBtemp = 0;
-
-int reply = 0;
-
+// holds R value from slave
+int Rtemp = 0;
+// holds the G value from slave
+int Gtemp = 0;
+// holds the B value from the slave
+int Btemp = 0;
/*
-**************************
- Objects
-**************************
+******************************************************
+ Objects
+******************************************************
*/
// UART connection to PC
Serial terminal(USBTX, USBRX);
@@ -116,18 +120,14 @@
PwmOut G(p28);
// B of RGB LED
PwmOut B(p26);
-// active-low 5-axis joystick
-// center, left_hi, right_hi, left_lo, right_lo
-BusIn joystick(p31, p32, p37, p39, p38);
-
+// interrupt to check for SPI errors
Ticker tock;
-
+/*
+******************************************************
+ Main Execution
+******************************************************
+*/
int main() {
- /*
- **************************
- Initializations
- **************************
- */
SerialInit();
AccInit();
LEDsInit();
@@ -138,52 +138,47 @@
terminal.printf("Initializing slave...........");
if(testSlave()) {
terminal.printf("done.");
- newline();
+ eol();
}
else {
terminal.printf("failed.");
- newline();
+ eol();
}
terminal.printf("Initializing timers..........");
// timer responsible for updating the LEDs
RtosTimer refresh_timer(LEDPush, osTimerPeriodic, (void *)0);
// 16.7Hz timer (60ms or ~1/2 of 30fps)
refresh_timer.start(60);
- RtosTimer update_timer(RGBconvert, osTimerPeriodic, (void *)0);
+ RtosTimer update_timer(RGBupdate, osTimerPeriodic, (void *)0);
// 10Hz timer (100ms)
update_timer.start(100);
terminal.printf("done.");
-
- newline();
+ eol();
+ terminal.printf("Initializing interrupts......");
tock.attach(checkSSEL_isr, 0.03);
- terminal.printf("Ticker started.");
- newline();
- newline();
+ terminal.printf("done.");
+ eol(); eol();
terminal.printf("Initialization complete.");
- newline();
- /*
- **************************
- Main Execution
- **************************
- */
+ eol();
+
+ // main's only job is to update the LED array with acc data
while(true) {
acc.read(accPos[0], accPos[1], accPos[2]);
acc_adj = getAngle();
LEDvals = mapLEDS(acc_adj);
}
}
-
/*
-**************************
- Function Definitions
-**************************
+******************************************************
+ Function Definitions
+******************************************************
*/
void SerialInit()
{
// initialize connection to PC. default: 8N1
terminal.baud(19200);
displayBanner();
- newline();
+ eol();
}
void AccInit()
@@ -195,14 +190,14 @@
// if we can successfully calibrate the accelerometer...
if(acc.calibrate()) {
- newline();
+ eol();
acc.getCalibrationOffsets(accCal[0], accCal[1], accCal[2]);
terminal.printf(" Offsets are (x,y,z): (%d, %d, %d)", accCal[0], accCal[1], accCal[2]);
- newline(); newline();
+ eol(); eol();
}
else {
terminal.printf("failed.");
- newline(); newline();
+ eol(); eol();
}
}
@@ -210,11 +205,11 @@
{
terminal.printf("Initializing LED array.......");
leds.format(8, 3); // 8-bit packet, polarity & phase mode 3
- leds.frequency(100000); // 1MHz SPI
+ leds.frequency(100000); // 1MHz
ld = 1;
LEDvals = 0x00;
terminal.printf("done.");
- newline();
+ eol();
}
void RgbInit()
@@ -228,10 +223,11 @@
B.period(.001);
B = 1.0;
terminal.printf("done.");
- newline();
+ eol();
}
-void newline()
+// inserts end-of-line
+void eol()
{
// newline = carriage return + line feed
terminal.putc('\n');
@@ -249,14 +245,14 @@
int i = 0;
for(int j = 0; j < 48; j++)
terminal.putc('*');
- newline();
+ eol();
while(i != 36) {
char c = banner[i];
terminal.putc(c);
i++;
}
- newline();
+ eol();
for(int j = 0; j < 48; j++)
terminal.putc('*');
@@ -268,11 +264,11 @@
// returns false if the mode is set to standby or unable to convert
if(acc.read(accPos[0], accPos[1], accPos[2])) {
terminal.printf("x: %d y: %d z: %d", accPos[0], accPos[1], accPos[2]);
- newline();
+ eol();
}
else {
terminal.printf("Unable to access MMA7455.");
- newline();
+ eol();
}
}
@@ -298,21 +294,6 @@
}
}
-// called by the refresh timer every 60ms
-void LEDPush(void const *args)
-{
- ld = 0; cs = 1;// active-low load, "open" lights, "lock" slave
- leds.write(LEDvals);
- ld = 1; cs = 0;// "lock" lights, "open" slave
-}
-
-void RGBPush(void)
-{
- R = r;
- G = g;
- B = b;
-}
-
/*
-0-90 degrees = 0-65 units (deg/unit ratio)
-90 - conversion = actual angle (a value of 65 means the device is flat)
@@ -327,6 +308,14 @@
return ( 90 - (3.0 * ((X2*deg*deg) - (X*cal) + C)) );
}
+// called by the refresh timer every 60ms
+void LEDPush(void const *args)
+{
+ ld = 0; cs = 1; // active-low load, "open" lights, "lock" slave
+ leds.write(LEDvals);
+ ld = 1; cs = 0; // "lock" lights, "open" slave
+}
+
// look-up table based on ranges
// this setup gives a nonlinear response from 0-90 degrees
unsigned char mapLEDS(double v)
@@ -378,54 +367,6 @@
}
}
-/*
- joystick: 0 1 2 3 4
- center left_hi right_hi left_lo right_lo
-*/
-void RGBpicker(void const *args)
-{
- tick++;
- if(tick > 1) {
- tick = 0;
- return;
- }
- // left : R
- if(!(joystick[3])) {
- if(R.read() == 0.0)
- r = 1.0;
- r = r - .02;
- }
- // right : B
- if(!(joystick[2])) {
- if(B.read() == 0.0)
- b = 1.0;
- b = b - .02;
- }
- // up : G
- if(!(joystick[4])) {
- if(G.read() == 0.0)
- g = 1.0;
- g = g - .02;
- }
- // down : Reset
- if(!(joystick[1])) {
- r = 1.0; g = 1.0; b = 1.0;
- }
- // center : confirm changes
- if(!joystick[0]) {
- RGBPush();
- terminal.printf("RGB updated: (%3.2f, %3.2f, %3.2f)", ((1 - R.read())*100), ((1 - G.read())*100), ((1 - B.read())*100));
- newline();
- }
-}
-
-void RGBconvert(void const *args){
- cs = 0; ld = 1;
- RGBtemp = leds.write(0);
- unpackRGB();
- cs = 1; ld = 0;
- }
-
// "chase" pattern to verify LED array
void testLED(void)
{
@@ -451,42 +392,32 @@
void testRGB(void)
{
r = 1.0; g = 1.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 0.0; g = 1.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = .6; g = 0.0; b = 0.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 1.0; g = 1.0; b = 0.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 1.0; g = 0.0; b = 0.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 1.0; g = 0.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 1.0; g = 1.0; b = 0.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 0.0; g = 0.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 0.0; g = 1.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
r = 1.0; g = 1.0; b = 1.0;
- RGBPush();
- wait_ms(150);
+ RGBPush(); wait_ms(150);
}
-// check if we got the proper reply from the slave.
+// check if we get the proper reply from the slave.
// this tells us if we've got a good comm channel
int testSlave(void)
{
- char t = 0;
+ int t = 0;
unsigned char reply = 0;
// 3s timeout
while(t < 300) {
@@ -503,39 +434,53 @@
return 0;
}
-void unpackRGB (){
- int tempR, tempG, tempB;
- //Shift R from bits 23:16 to 7:0 and XOR with 0x00 to isolate data.
- terminal.printf("RGB: %h",RGBtemp);
- newline();
- newline();
- tempR = (RGBtemp &0x00FF0000)>>16;
- tempG = (RGBtemp &0x0000FF00)>>8;
- tempB = RGBtemp &0x000000FF;
+// assigns the current value to the PWM object
+void RGBPush(void)
+{
+ R = r;
+ G = g;
+ B = b;
+}
+
+/*
+ Cycle thru RGB values using the status register (sentStatus) and
+ request the next value which will be collected one cycle later.
+ For example, we request red first but actually get red when we ask for
+ green, and green when we ask for blue, and blue when we ask for red.
+*/
+void RGBupdate(void const *args){
+ cs = 0; ld = 1;
+ if(!sentStatus[0]) {
+ sentStatus[0] = 1;
+ Btemp = leds.write(R_CODE);
+ }
+ else if(!sentStatus[1]) {
+ sentStatus[1] = 1;
+ Rtemp = leds.write(G_CODE);
+ }
+ else if(!sentStatus[2]) {
+ sentStatus[0] = 0;
+ sentStatus[1] = 0;
+ Gtemp = leds.write(B_CODE);
+ unpackRGB(Rtemp, Gtemp, Btemp);
+ }
+ cs = 1; ld = 0;
+}
+
+// convert an integer representation of a color to it's float equivalent
+void unpackRGB(int tempR, int tempG, int tempB)
+{
r = (float(tempR))/255.0;
- //Shift G from bits 15:8 to 7:0 and XOR with 0x00 to isolate data.
g = (float(tempG))/255.0;
- //XOR B ^ 0x00 to isolate data.
b = (float(tempB))/255.0;
- printf("R: %f \n\r G: %f \n\r B: %f\n\r", r,g,b);
- newline();
RGBPush();
- }
-
-void packRGB (int R, int G, int B){
- RGB = 0;
- //Shift R from bits 23:16 to 7:0 and XOR with 0x00 to isolate data.
- RGB = RGB|(int(r*255.0) << 16);
- //Shift G from bits 15:8 to 7:0 and XOR with 0x00 to isolate data.
- RGB = RGB|(int(g*255.0) << 8);
- //XOR B ^ 0x00 to isolate data.
- RGB = RGB|(int(b*255.0) );
- //spi.reply(RGB);
- }
-
+}
+
+// simple SPI error checking
+// both SSEL's shouldn't be active at the same time
void checkSSEL_isr(){
if((~(ld | cs)) == 0){
terminal.printf("ERROR: Both SPI Slave Selects are active!");
- newline();
+ eol();
}
}
\ No newline at end of file