The Accelerometer and Slope program

Dependencies:   MMA8452 PowerControl mbed

Committer:
NicolasXu
Date:
Mon May 11 21:18:42 2015 +0000
Revision:
0:7f98d386be37
the Acceleration and slope program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
NicolasXu 0:7f98d386be37 1 /**
NicolasXu 0:7f98d386be37 2 @file N5110.cpp
NicolasXu 0:7f98d386be37 3
NicolasXu 0:7f98d386be37 4 @brief Member functions implementations
NicolasXu 0:7f98d386be37 5 @brief The fundamental code of a Accelerometer and SpiritLevel
NicolasXu 0:7f98d386be37 6 @brief SpiritLevel 1.0
NicolasXu 0:7f98d386be37 7 @author Bo Xu
NicolasXu 0:7f98d386be37 8 @date May 2015
NicolasXu 0:7f98d386be37 9 */
NicolasXu 0:7f98d386be37 10 #include "mbed.h"
NicolasXu 0:7f98d386be37 11 #include "N5110.h"
NicolasXu 0:7f98d386be37 12 #include "MMA8452.h"
NicolasXu 0:7f98d386be37 13 #include "PowerControl/PowerControl.h"
NicolasXu 0:7f98d386be37 14 #include "PowerControl/EthernetPowerControl.h"
NicolasXu 0:7f98d386be37 15
NicolasXu 0:7f98d386be37 16 #define USR_POWERDOWN (0x104)
NicolasXu 0:7f98d386be37 17
NicolasXu 0:7f98d386be37 18 /**
NicolasXu 0:7f98d386be37 19 @namespace button
NicolasXu 0:7f98d386be37 20 @brief AnalogIn for application button
NicolasXu 0:7f98d386be37 21 */
NicolasXu 0:7f98d386be37 22 InterruptIn button(p16);
NicolasXu 0:7f98d386be37 23
NicolasXu 0:7f98d386be37 24 #define accelerator 0
NicolasXu 0:7f98d386be37 25 #define slope 1
NicolasXu 0:7f98d386be37 26
NicolasXu 0:7f98d386be37 27 int function = accelerator;
NicolasXu 0:7f98d386be37 28 /**
NicolasXu 0:7f98d386be37 29 namespace led
NicolasXu 0:7f98d386be37 30 @brief Pwmout for SpiritLevel LED
NicolasXu 0:7f98d386be37 31 */
NicolasXu 0:7f98d386be37 32 PwmOut led(p24);
NicolasXu 0:7f98d386be37 33
NicolasXu 0:7f98d386be37 34 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
NicolasXu 0:7f98d386be37 35 {
NicolasXu 0:7f98d386be37 36
NicolasXu 0:7f98d386be37 37 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
NicolasXu 0:7f98d386be37 38 initSPI();
NicolasXu 0:7f98d386be37 39
NicolasXu 0:7f98d386be37 40 // set up pins as required
NicolasXu 0:7f98d386be37 41 led = new PwmOut(ledPin);
NicolasXu 0:7f98d386be37 42 pwr = new DigitalOut(pwrPin);
NicolasXu 0:7f98d386be37 43 sce = new DigitalOut(scePin);
NicolasXu 0:7f98d386be37 44 rst = new DigitalOut(rstPin);
NicolasXu 0:7f98d386be37 45 dc = new DigitalOut(dcPin);
NicolasXu 0:7f98d386be37 46
NicolasXu 0:7f98d386be37 47 }
NicolasXu 0:7f98d386be37 48
NicolasXu 0:7f98d386be37 49 /**
NicolasXu 0:7f98d386be37 50 initialize the N5110 and declare the pins it connected to the microcontroller
NicolasXu 0:7f98d386be37 51 */
NicolasXu 0:7f98d386be37 52 N5110 lcd(p7, p8, p9, p10, p11, p13, p26);
NicolasXu 0:7f98d386be37 53 /**
NicolasXu 0:7f98d386be37 54 initialize the MMA8452 sensor and declare the pins it connected to the microcontroller
NicolasXu 0:7f98d386be37 55 */
NicolasXu 0:7f98d386be37 56 MMA8452 mma8452(p28, p27);
NicolasXu 0:7f98d386be37 57
NicolasXu 0:7f98d386be37 58 Serial serial (USBTX, USBRX);
NicolasXu 0:7f98d386be37 59
NicolasXu 0:7f98d386be37 60 int semihost_powerdown() {
NicolasXu 0:7f98d386be37 61 uint32_t arg;
NicolasXu 0:7f98d386be37 62 return __semihost(USR_POWERDOWN, &arg);
NicolasXu 0:7f98d386be37 63 }
NicolasXu 0:7f98d386be37 64
NicolasXu 0:7f98d386be37 65 // initialise function - powers up and sends the initialisation commands
NicolasXu 0:7f98d386be37 66 void N5110::init()
NicolasXu 0:7f98d386be37 67 {
NicolasXu 0:7f98d386be37 68 turnOn(); // power up
NicolasXu 0:7f98d386be37 69 wait_ms(10); // small delay seems to prevent spurious pixels during mbed reset
NicolasXu 0:7f98d386be37 70 reset(); // reset LCD - must be done within 100 ms
NicolasXu 0:7f98d386be37 71
NicolasXu 0:7f98d386be37 72 // function set - extended
NicolasXu 0:7f98d386be37 73 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
NicolasXu 0:7f98d386be37 74 // Don't completely understand these parameters - they seem to work as they are
NicolasXu 0:7f98d386be37 75 // Consult the datasheet if you need to change them
NicolasXu 0:7f98d386be37 76 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library
NicolasXu 0:7f98d386be37 77 sendCommand(CMD_TC_TEMP_2); // temperature control
NicolasXu 0:7f98d386be37 78 sendCommand(CMD_BI_MUX_48); // bias
NicolasXu 0:7f98d386be37 79
NicolasXu 0:7f98d386be37 80 // function set - basic
NicolasXu 0:7f98d386be37 81 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
NicolasXu 0:7f98d386be37 82 normalMode(); // normal video mode by default
NicolasXu 0:7f98d386be37 83 sendCommand(CMD_DC_NORMAL_MODE); // black on white
NicolasXu 0:7f98d386be37 84
NicolasXu 0:7f98d386be37 85 // RAM is undefined at power-up so clear
NicolasXu 0:7f98d386be37 86 clearRAM();
NicolasXu 0:7f98d386be37 87
NicolasXu 0:7f98d386be37 88 }
NicolasXu 0:7f98d386be37 89
NicolasXu 0:7f98d386be37 90 // sets normal video mode (black on white)
NicolasXu 0:7f98d386be37 91 void N5110::normalMode()
NicolasXu 0:7f98d386be37 92 {
NicolasXu 0:7f98d386be37 93 sendCommand(CMD_DC_NORMAL_MODE);
NicolasXu 0:7f98d386be37 94
NicolasXu 0:7f98d386be37 95 }
NicolasXu 0:7f98d386be37 96
NicolasXu 0:7f98d386be37 97 // sets normal video mode (white on black)
NicolasXu 0:7f98d386be37 98 void N5110::inverseMode()
NicolasXu 0:7f98d386be37 99 {
NicolasXu 0:7f98d386be37 100 sendCommand(CMD_DC_INVERT_VIDEO);
NicolasXu 0:7f98d386be37 101 }
NicolasXu 0:7f98d386be37 102
NicolasXu 0:7f98d386be37 103 /**
NicolasXu 0:7f98d386be37 104 function for the function button
NicolasXu 0:7f98d386be37 105 */
NicolasXu 0:7f98d386be37 106 void buttonPressed(){
NicolasXu 0:7f98d386be37 107
NicolasXu 0:7f98d386be37 108 function = !function;
NicolasXu 0:7f98d386be37 109
NicolasXu 0:7f98d386be37 110 }
NicolasXu 0:7f98d386be37 111
NicolasXu 0:7f98d386be37 112 // function to power up the LCD and backlight
NicolasXu 0:7f98d386be37 113 void N5110::turnOn()
NicolasXu 0:7f98d386be37 114 {
NicolasXu 0:7f98d386be37 115 // set brightness of LED - 0.0 to 1.0 - default is 50%
NicolasXu 0:7f98d386be37 116 setBrightness( 0.2);
NicolasXu 0:7f98d386be37 117 pwr->write(1); // apply power
NicolasXu 0:7f98d386be37 118 }
NicolasXu 0:7f98d386be37 119
NicolasXu 0:7f98d386be37 120 // function to power down LCD
NicolasXu 0:7f98d386be37 121 void N5110::turnOff()
NicolasXu 0:7f98d386be37 122 {
NicolasXu 0:7f98d386be37 123 setBrightness(0.0); // turn backlight off
NicolasXu 0:7f98d386be37 124 clearRAM(); // clear RAM to ensure specified current consumption
NicolasXu 0:7f98d386be37 125 // send command to ensure we are in basic mode
NicolasXu 0:7f98d386be37 126 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
NicolasXu 0:7f98d386be37 127 // clear the display
NicolasXu 0:7f98d386be37 128 sendCommand(CMD_DC_CLEAR_DISPLAY);
NicolasXu 0:7f98d386be37 129 // enter the extended mode and power down
NicolasXu 0:7f98d386be37 130 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
NicolasXu 0:7f98d386be37 131 // small delay and then turn off the power pin
NicolasXu 0:7f98d386be37 132 wait_ms(10);
NicolasXu 0:7f98d386be37 133 pwr->write(0);
NicolasXu 0:7f98d386be37 134
NicolasXu 0:7f98d386be37 135 }
NicolasXu 0:7f98d386be37 136
NicolasXu 0:7f98d386be37 137 // function to change LED backlight brightness
NicolasXu 0:7f98d386be37 138 void N5110::setBrightness(float brightness)
NicolasXu 0:7f98d386be37 139 {
NicolasXu 0:7f98d386be37 140 // check whether brightness is within range
NicolasXu 0:7f98d386be37 141 if (brightness < 0.0)
NicolasXu 0:7f98d386be37 142 brightness = 0.0;
NicolasXu 0:7f98d386be37 143 if (brightness > 1.0)
NicolasXu 0:7f98d386be37 144 brightness = 1.0;
NicolasXu 0:7f98d386be37 145 // set PWM duty cycle
NicolasXu 0:7f98d386be37 146 led->write(brightness);
NicolasXu 0:7f98d386be37 147 }
NicolasXu 0:7f98d386be37 148
NicolasXu 0:7f98d386be37 149
NicolasXu 0:7f98d386be37 150 // pulse the active low reset line
NicolasXu 0:7f98d386be37 151 void N5110::reset()
NicolasXu 0:7f98d386be37 152 {
NicolasXu 0:7f98d386be37 153 rst->write(0); // reset the LCD
NicolasXu 0:7f98d386be37 154 rst->write(1);
NicolasXu 0:7f98d386be37 155 }
NicolasXu 0:7f98d386be37 156
NicolasXu 0:7f98d386be37 157 // function to initialise SPI peripheral
NicolasXu 0:7f98d386be37 158 void N5110::initSPI()
NicolasXu 0:7f98d386be37 159 {
NicolasXu 0:7f98d386be37 160 spi->format(8,1); // 8 bits, Mode 1 - polarity 0, phase 1 - base value of clock is 0, data captured on falling edge/propagated on rising edge
NicolasXu 0:7f98d386be37 161 spi->frequency(4000000); // maximum of screen is 4 MHz
NicolasXu 0:7f98d386be37 162 }
NicolasXu 0:7f98d386be37 163
NicolasXu 0:7f98d386be37 164 // send a command to the display
NicolasXu 0:7f98d386be37 165 void N5110::sendCommand(unsigned char command)
NicolasXu 0:7f98d386be37 166 {
NicolasXu 0:7f98d386be37 167 dc->write(0); // set DC low for command
NicolasXu 0:7f98d386be37 168 sce->write(0); // set CE low to begin frame
NicolasXu 0:7f98d386be37 169 spi->write(command); // send command
NicolasXu 0:7f98d386be37 170 dc->write(1); // turn back to data by default
NicolasXu 0:7f98d386be37 171 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
NicolasXu 0:7f98d386be37 172
NicolasXu 0:7f98d386be37 173 }
NicolasXu 0:7f98d386be37 174
NicolasXu 0:7f98d386be37 175 // send data to the display at the current XY address
NicolasXu 0:7f98d386be37 176 // dc is set to 1 (i.e. data) after sending a command and so should
NicolasXu 0:7f98d386be37 177 // be the default mode.
NicolasXu 0:7f98d386be37 178 void N5110::sendData(unsigned char data)
NicolasXu 0:7f98d386be37 179 {
NicolasXu 0:7f98d386be37 180 sce->write(0); // set CE low to begin frame
NicolasXu 0:7f98d386be37 181 spi->write(data);
NicolasXu 0:7f98d386be37 182 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
NicolasXu 0:7f98d386be37 183 }
NicolasXu 0:7f98d386be37 184
NicolasXu 0:7f98d386be37 185 // this function writes 0 to the 504 bytes to clear the RAM
NicolasXu 0:7f98d386be37 186 void N5110::clearRAM()
NicolasXu 0:7f98d386be37 187 {
NicolasXu 0:7f98d386be37 188 int i;
NicolasXu 0:7f98d386be37 189 sce->write(0); //set CE low to begin frame
NicolasXu 0:7f98d386be37 190 for(i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes
NicolasXu 0:7f98d386be37 191 spi->write(0x00); // send 0's
NicolasXu 0:7f98d386be37 192 }
NicolasXu 0:7f98d386be37 193 sce->write(1); // set CE high to end frame
NicolasXu 0:7f98d386be37 194
NicolasXu 0:7f98d386be37 195 }
NicolasXu 0:7f98d386be37 196
NicolasXu 0:7f98d386be37 197 // function to set the XY address in RAM for subsequenct data write
NicolasXu 0:7f98d386be37 198 void N5110::setXYAddress(int x, int y)
NicolasXu 0:7f98d386be37 199 {
NicolasXu 0:7f98d386be37 200 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
NicolasXu 0:7f98d386be37 201 sendCommand(0x80 | x); // send addresses to display with relevant mask
NicolasXu 0:7f98d386be37 202 sendCommand(0x40 | y);
NicolasXu 0:7f98d386be37 203 }
NicolasXu 0:7f98d386be37 204 }
NicolasXu 0:7f98d386be37 205
NicolasXu 0:7f98d386be37 206 // These functions are used to set, clear and get the value of pixels in the display
NicolasXu 0:7f98d386be37 207 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
NicolasXu 0:7f98d386be37 208 // function must be called after set and clear in order to update the display
NicolasXu 0:7f98d386be37 209 void N5110::setPixel(int x, int y)
NicolasXu 0:7f98d386be37 210 {
NicolasXu 0:7f98d386be37 211 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
NicolasXu 0:7f98d386be37 212 // calculate bank and shift 1 to required position in the data byte
NicolasXu 0:7f98d386be37 213 buffer[x][y/8] |= (1 << y%8);
NicolasXu 0:7f98d386be37 214 }
NicolasXu 0:7f98d386be37 215 }
NicolasXu 0:7f98d386be37 216
NicolasXu 0:7f98d386be37 217 void N5110::clearPixel(int x, int y)
NicolasXu 0:7f98d386be37 218 {
NicolasXu 0:7f98d386be37 219 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
NicolasXu 0:7f98d386be37 220 // calculate bank and shift 1 to required position (using bit clear)
NicolasXu 0:7f98d386be37 221 buffer[x][y/8] &= ~(1 << y%8);
NicolasXu 0:7f98d386be37 222 }
NicolasXu 0:7f98d386be37 223 }
NicolasXu 0:7f98d386be37 224
NicolasXu 0:7f98d386be37 225 int N5110::getPixel(int x, int y)
NicolasXu 0:7f98d386be37 226 {
NicolasXu 0:7f98d386be37 227 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
NicolasXu 0:7f98d386be37 228 // return relevant bank and mask required bit
NicolasXu 0:7f98d386be37 229 return (int) buffer[x][y/8] & (1 << y%8);
NicolasXu 0:7f98d386be37 230 // note this does not necessarily return 1 - a non-zero number represents a pixel
NicolasXu 0:7f98d386be37 231 } else {
NicolasXu 0:7f98d386be37 232 return 0;
NicolasXu 0:7f98d386be37 233 }
NicolasXu 0:7f98d386be37 234 }
NicolasXu 0:7f98d386be37 235
NicolasXu 0:7f98d386be37 236 // function to refresh the display
NicolasXu 0:7f98d386be37 237 void N5110::refresh()
NicolasXu 0:7f98d386be37 238 {
NicolasXu 0:7f98d386be37 239 int i,j;
NicolasXu 0:7f98d386be37 240
NicolasXu 0:7f98d386be37 241 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
NicolasXu 0:7f98d386be37 242 // address auto increments after printing string, so buffer[0][0] will not coincide
NicolasXu 0:7f98d386be37 243 // with top-left pixel after priting string
NicolasXu 0:7f98d386be37 244
NicolasXu 0:7f98d386be37 245 sce->write(0); //set CE low to begin frame
NicolasXu 0:7f98d386be37 246
NicolasXu 0:7f98d386be37 247 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
NicolasXu 0:7f98d386be37 248 for(i = 0; i < WIDTH; i++) {
NicolasXu 0:7f98d386be37 249 spi->write(buffer[i][j]); // send buffer
NicolasXu 0:7f98d386be37 250 }
NicolasXu 0:7f98d386be37 251 }
NicolasXu 0:7f98d386be37 252 sce->write(1); // set CE high to end frame
NicolasXu 0:7f98d386be37 253
NicolasXu 0:7f98d386be37 254 }
NicolasXu 0:7f98d386be37 255
NicolasXu 0:7f98d386be37 256 // fills the buffer with random bytes. Can be used to test the display.
NicolasXu 0:7f98d386be37 257 // The rand() function isn't seeded so it probably creates the same pattern everytime
NicolasXu 0:7f98d386be37 258 void N5110::randomiseBuffer()
NicolasXu 0:7f98d386be37 259 {
NicolasXu 0:7f98d386be37 260 int i,j;
NicolasXu 0:7f98d386be37 261 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
NicolasXu 0:7f98d386be37 262 for(i = 0; i < WIDTH; i++) {
NicolasXu 0:7f98d386be37 263 buffer[i][j] = rand()%256; // generate random byte
NicolasXu 0:7f98d386be37 264 }
NicolasXu 0:7f98d386be37 265 }
NicolasXu 0:7f98d386be37 266
NicolasXu 0:7f98d386be37 267 }
NicolasXu 0:7f98d386be37 268
NicolasXu 0:7f98d386be37 269 // function to print 5x7 font
NicolasXu 0:7f98d386be37 270 void N5110::printChar(char c,int x,int y)
NicolasXu 0:7f98d386be37 271 {
NicolasXu 0:7f98d386be37 272 if (y>=0 && y<BANKS) { // check if printing in range of y banks
NicolasXu 0:7f98d386be37 273
NicolasXu 0:7f98d386be37 274 for (int i = 0; i < 5 ; i++ ) {
NicolasXu 0:7f98d386be37 275 int pixel_x = x+i;
NicolasXu 0:7f98d386be37 276 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
NicolasXu 0:7f98d386be37 277 break;
NicolasXu 0:7f98d386be37 278 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i];
NicolasXu 0:7f98d386be37 279 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
NicolasXu 0:7f98d386be37 280 }
NicolasXu 0:7f98d386be37 281
NicolasXu 0:7f98d386be37 282 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
NicolasXu 0:7f98d386be37 283 }
NicolasXu 0:7f98d386be37 284 }
NicolasXu 0:7f98d386be37 285
NicolasXu 0:7f98d386be37 286 // function to print string at specified position
NicolasXu 0:7f98d386be37 287 void N5110::printString(const char * str,int x,int y)
NicolasXu 0:7f98d386be37 288 {
NicolasXu 0:7f98d386be37 289 if (y>=0 && y<BANKS) { // check if printing in range of y banks
NicolasXu 0:7f98d386be37 290
NicolasXu 0:7f98d386be37 291 int n = 0 ; // counter for number of characters in string
NicolasXu 0:7f98d386be37 292 // loop through string and print character
NicolasXu 0:7f98d386be37 293 while(*str) {
NicolasXu 0:7f98d386be37 294
NicolasXu 0:7f98d386be37 295 // writes the character bitmap data to the buffer, so that
NicolasXu 0:7f98d386be37 296 // text and pixels can be displayed at the same time
NicolasXu 0:7f98d386be37 297 for (int i = 0; i < 5 ; i++ ) {
NicolasXu 0:7f98d386be37 298 int pixel_x = x+i+n*6;
NicolasXu 0:7f98d386be37 299 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
NicolasXu 0:7f98d386be37 300 break;
NicolasXu 0:7f98d386be37 301 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i];
NicolasXu 0:7f98d386be37 302 }
NicolasXu 0:7f98d386be37 303
NicolasXu 0:7f98d386be37 304 str++; // go to next character in string
NicolasXu 0:7f98d386be37 305
NicolasXu 0:7f98d386be37 306 n++; // increment index
NicolasXu 0:7f98d386be37 307
NicolasXu 0:7f98d386be37 308 }
NicolasXu 0:7f98d386be37 309
NicolasXu 0:7f98d386be37 310 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
NicolasXu 0:7f98d386be37 311 }
NicolasXu 0:7f98d386be37 312 }
NicolasXu 0:7f98d386be37 313
NicolasXu 0:7f98d386be37 314 // function to clear the screen
NicolasXu 0:7f98d386be37 315 void N5110::clear()
NicolasXu 0:7f98d386be37 316 {
NicolasXu 0:7f98d386be37 317 clearBuffer(); // clear the buffer then call the refresh function
NicolasXu 0:7f98d386be37 318 refresh();
NicolasXu 0:7f98d386be37 319 }
NicolasXu 0:7f98d386be37 320
NicolasXu 0:7f98d386be37 321 // function to clear the buffer
NicolasXu 0:7f98d386be37 322 void N5110::clearBuffer()
NicolasXu 0:7f98d386be37 323 {
NicolasXu 0:7f98d386be37 324 int i,j;
NicolasXu 0:7f98d386be37 325 for (i=0; i<WIDTH; i++) { // loop through the banks and set the buffer to 0
NicolasXu 0:7f98d386be37 326 for (j=0; j<BANKS; j++) {
NicolasXu 0:7f98d386be37 327 buffer[i][j]=0;
NicolasXu 0:7f98d386be37 328 }
NicolasXu 0:7f98d386be37 329 }
NicolasXu 0:7f98d386be37 330 }
NicolasXu 0:7f98d386be37 331
NicolasXu 0:7f98d386be37 332 // function to plot array on display
NicolasXu 0:7f98d386be37 333 void N5110::plotArray(float array[])
NicolasXu 0:7f98d386be37 334 {
NicolasXu 0:7f98d386be37 335
NicolasXu 0:7f98d386be37 336 int i;
NicolasXu 0:7f98d386be37 337
NicolasXu 0:7f98d386be37 338 for (i=0; i<WIDTH; i++) { // loop through array
NicolasXu 0:7f98d386be37 339 // elements are normalised from 0.0 to 1.0, so multiply
NicolasXu 0:7f98d386be37 340 // by 47 to convert to pixel range, and subtract from 47
NicolasXu 0:7f98d386be37 341 // since top-left is 0,0 in the display geometry
NicolasXu 0:7f98d386be37 342 setPixel(i,47 - int(array[i]*47.0));
NicolasXu 0:7f98d386be37 343 }
NicolasXu 0:7f98d386be37 344
NicolasXu 0:7f98d386be37 345 refresh();
NicolasXu 0:7f98d386be37 346
NicolasXu 0:7f98d386be37 347 }
NicolasXu 0:7f98d386be37 348
NicolasXu 0:7f98d386be37 349 // function to draw circle
NicolasXu 0:7f98d386be37 350 void N5110:: drawCircle(int x0,int y0,int radius,int fill)
NicolasXu 0:7f98d386be37 351 {
NicolasXu 0:7f98d386be37 352 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
NicolasXu 0:7f98d386be37 353 int x = radius;
NicolasXu 0:7f98d386be37 354 int y = 0;
NicolasXu 0:7f98d386be37 355 int radiusError = 1-x;
NicolasXu 0:7f98d386be37 356
NicolasXu 0:7f98d386be37 357 while(x >= y) {
NicolasXu 0:7f98d386be37 358
NicolasXu 0:7f98d386be37 359 // if transparent, just draw outline
NicolasXu 0:7f98d386be37 360 if (fill == 0) {
NicolasXu 0:7f98d386be37 361 setPixel( x + x0, y + y0);
NicolasXu 0:7f98d386be37 362 setPixel(-x + x0, y + y0);
NicolasXu 0:7f98d386be37 363 setPixel( y + x0, x + y0);
NicolasXu 0:7f98d386be37 364 setPixel(-y + x0, x + y0);
NicolasXu 0:7f98d386be37 365 setPixel(-y + x0, -x + y0);
NicolasXu 0:7f98d386be37 366 setPixel( y + x0, -x + y0);
NicolasXu 0:7f98d386be37 367 setPixel( x + x0, -y + y0);
NicolasXu 0:7f98d386be37 368 setPixel(-x + x0, -y + y0);
NicolasXu 0:7f98d386be37 369 } else { // drawing filled circle, so draw lines between points at same y value
NicolasXu 0:7f98d386be37 370
NicolasXu 0:7f98d386be37 371 int type = (fill==1) ? 1:0; // black or white fill
NicolasXu 0:7f98d386be37 372
NicolasXu 0:7f98d386be37 373 drawLine(x+x0,y+y0,-x+x0,y+y0,type);
NicolasXu 0:7f98d386be37 374 drawLine(y+x0,x+y0,-y+x0,x+y0,type);
NicolasXu 0:7f98d386be37 375 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type);
NicolasXu 0:7f98d386be37 376 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type);
NicolasXu 0:7f98d386be37 377 }
NicolasXu 0:7f98d386be37 378
NicolasXu 0:7f98d386be37 379
NicolasXu 0:7f98d386be37 380 y++;
NicolasXu 0:7f98d386be37 381 if (radiusError<0) {
NicolasXu 0:7f98d386be37 382 radiusError += 2 * y + 1;
NicolasXu 0:7f98d386be37 383 } else {
NicolasXu 0:7f98d386be37 384 x--;
NicolasXu 0:7f98d386be37 385 radiusError += 2 * (y - x) + 1;
NicolasXu 0:7f98d386be37 386 }
NicolasXu 0:7f98d386be37 387 }
NicolasXu 0:7f98d386be37 388
NicolasXu 0:7f98d386be37 389 }
NicolasXu 0:7f98d386be37 390
NicolasXu 0:7f98d386be37 391 void N5110::drawLine(int x0,int y0,int x1,int y1,int type)
NicolasXu 0:7f98d386be37 392 {
NicolasXu 0:7f98d386be37 393 int y_range = y1-y0; // calc range of y and x
NicolasXu 0:7f98d386be37 394 int x_range = x1-x0;
NicolasXu 0:7f98d386be37 395 int start,stop,step;
NicolasXu 0:7f98d386be37 396
NicolasXu 0:7f98d386be37 397 // if dotted line, set step to 2, else step is 1
NicolasXu 0:7f98d386be37 398 step = (type==2) ? 2:1;
NicolasXu 0:7f98d386be37 399
NicolasXu 0:7f98d386be37 400 // make sure we loop over the largest range to get the most pixels on the display
NicolasXu 0:7f98d386be37 401 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
NicolasXu 0:7f98d386be37 402 // or else we'll only end up with 1 pixel in the x column
NicolasXu 0:7f98d386be37 403 if ( abs(x_range) > abs(y_range) ) {
NicolasXu 0:7f98d386be37 404
NicolasXu 0:7f98d386be37 405 // ensure we loop from smallest to largest or else for-loop won't run as expected
NicolasXu 0:7f98d386be37 406 start = x1>x0 ? x0:x1;
NicolasXu 0:7f98d386be37 407 stop = x1>x0 ? x1:x0;
NicolasXu 0:7f98d386be37 408
NicolasXu 0:7f98d386be37 409 // loop between x pixels
NicolasXu 0:7f98d386be37 410 for (int x = start; x<= stop ; x+=step) {
NicolasXu 0:7f98d386be37 411 // do linear interpolation
NicolasXu 0:7f98d386be37 412 int y = y0 + (y1-y0)*(x-x0)/(x1-x0);
NicolasXu 0:7f98d386be37 413
NicolasXu 0:7f98d386be37 414 if (type == 0) // if 'white' line, turn off pixel
NicolasXu 0:7f98d386be37 415 clearPixel(x,y);
NicolasXu 0:7f98d386be37 416 else
NicolasXu 0:7f98d386be37 417 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
NicolasXu 0:7f98d386be37 418 }
NicolasXu 0:7f98d386be37 419 } else {
NicolasXu 0:7f98d386be37 420
NicolasXu 0:7f98d386be37 421 // ensure we loop from smallest to largest or else for-loop won't run as expected
NicolasXu 0:7f98d386be37 422 start = y1>y0 ? y0:y1;
NicolasXu 0:7f98d386be37 423 stop = y1>y0 ? y1:y0;
NicolasXu 0:7f98d386be37 424
NicolasXu 0:7f98d386be37 425 for (int y = start; y<= stop ; y+=step) {
NicolasXu 0:7f98d386be37 426 // do linear interpolation
NicolasXu 0:7f98d386be37 427 int x = x0 + (x1-x0)*(y-y0)/(y1-y0);
NicolasXu 0:7f98d386be37 428
NicolasXu 0:7f98d386be37 429 if (type == 0) // if 'white' line, turn off pixel
NicolasXu 0:7f98d386be37 430 clearPixel(x,y);
NicolasXu 0:7f98d386be37 431 else
NicolasXu 0:7f98d386be37 432 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
NicolasXu 0:7f98d386be37 433
NicolasXu 0:7f98d386be37 434 }
NicolasXu 0:7f98d386be37 435 }
NicolasXu 0:7f98d386be37 436
NicolasXu 0:7f98d386be37 437 }
NicolasXu 0:7f98d386be37 438
NicolasXu 0:7f98d386be37 439 void N5110::drawRect(int x0,int y0,int width,int height,int fill)
NicolasXu 0:7f98d386be37 440 {
NicolasXu 0:7f98d386be37 441
NicolasXu 0:7f98d386be37 442 if (fill == 0) { // transparent, just outline
NicolasXu 0:7f98d386be37 443 drawLine(x0,y0,x0+width,y0,1); // top
NicolasXu 0:7f98d386be37 444 drawLine(x0,y0+height,x0+width,y0+height,1); // bottom
NicolasXu 0:7f98d386be37 445 drawLine(x0,y0,x0,y0+height,1); // left
NicolasXu 0:7f98d386be37 446 drawLine(x0+width,y0,x0+width,y0+height,1); // right
NicolasXu 0:7f98d386be37 447 } else { // filled rectangle
NicolasXu 0:7f98d386be37 448 int type = (fill==1) ? 1:0; // black or white fill
NicolasXu 0:7f98d386be37 449 for (int y = y0; y<= y0+height; y++) { // loop through rows of rectangle
NicolasXu 0:7f98d386be37 450 drawLine(x0,y,x0+width,y,type); // draw line across screen
NicolasXu 0:7f98d386be37 451 }
NicolasXu 0:7f98d386be37 452 }
NicolasXu 0:7f98d386be37 453
NicolasXu 0:7f98d386be37 454 }
NicolasXu 0:7f98d386be37 455
NicolasXu 0:7f98d386be37 456
NicolasXu 0:7f98d386be37 457
NicolasXu 0:7f98d386be37 458 int main(){
NicolasXu 0:7f98d386be37 459 /**
NicolasXu 0:7f98d386be37 460 Power down the Ethernet in order to save power
NicolasXu 0:7f98d386be37 461 */
NicolasXu 0:7f98d386be37 462 semihost_powerdown();
NicolasXu 0:7f98d386be37 463
NicolasXu 0:7f98d386be37 464 PHY_PowerDown();
NicolasXu 0:7f98d386be37 465 /**
NicolasXu 0:7f98d386be37 466 initialize the LCD display and MMA8452 sensor
NicolasXu 0:7f98d386be37 467 */
NicolasXu 0:7f98d386be37 468 lcd.init();
NicolasXu 0:7f98d386be37 469 mma8452.init();
NicolasXu 0:7f98d386be37 470
NicolasXu 0:7f98d386be37 471 Acceleration acceleration;
NicolasXu 0:7f98d386be37 472
NicolasXu 0:7f98d386be37 473 wait(.001);
NicolasXu 0:7f98d386be37 474
NicolasXu 0:7f98d386be37 475 button.rise(&buttonPressed);
NicolasXu 0:7f98d386be37 476
NicolasXu 0:7f98d386be37 477
NicolasXu 0:7f98d386be37 478 while (1){
NicolasXu 0:7f98d386be37 479 /**
NicolasXu 0:7f98d386be37 480 Read values from the MMA8452 sensor
NicolasXu 0:7f98d386be37 481 */
NicolasXu 0:7f98d386be37 482 acceleration = mma8452.readValues();
NicolasXu 0:7f98d386be37 483
NicolasXu 0:7f98d386be37 484 /**
NicolasXu 0:7f98d386be37 485 state two different applications of the device
NicolasXu 0:7f98d386be37 486 function=0 - Accelerometer
NicolasXu 0:7f98d386be37 487 function=1 - Slope
NicolasXu 0:7f98d386be37 488 */
NicolasXu 0:7f98d386be37 489 switch(function){
NicolasXu 0:7f98d386be37 490 case accelerator:
NicolasXu 0:7f98d386be37 491
NicolasXu 0:7f98d386be37 492 /**
NicolasXu 0:7f98d386be37 493 the algorithm of the acceleration
NicolasXu 0:7f98d386be37 494 */
NicolasXu 0:7f98d386be37 495 char buffer[14];
NicolasXu 0:7f98d386be37 496 int length = sprintf(buffer,"Acceleration");
NicolasXu 0:7f98d386be37 497 char buffer2[14];
NicolasXu 0:7f98d386be37 498 length = sprintf(buffer2,"x = %.2f g", acceleration.x);
NicolasXu 0:7f98d386be37 499 char buffer3[14];
NicolasXu 0:7f98d386be37 500 length = sprintf(buffer3,"y = %.2f g", acceleration.y);
NicolasXu 0:7f98d386be37 501 char buffer4[14];
NicolasXu 0:7f98d386be37 502 length = sprintf(buffer4,"z = %.2f g", acceleration.z);
NicolasXu 0:7f98d386be37 503 /**
NicolasXu 0:7f98d386be37 504 draw a rectangle and print the acceleration
NicolasXu 0:7f98d386be37 505 */
NicolasXu 0:7f98d386be37 506 lcd.drawRect(0,0,83,47,0);
NicolasXu 0:7f98d386be37 507 lcd.printString(buffer,4,1);
NicolasXu 0:7f98d386be37 508 lcd.printString(buffer2,4,2);
NicolasXu 0:7f98d386be37 509 lcd.printString(buffer3,4,3);
NicolasXu 0:7f98d386be37 510 lcd.printString(buffer4,4,4);
NicolasXu 0:7f98d386be37 511 wait(0.1);
NicolasXu 0:7f98d386be37 512 lcd.clear();
NicolasXu 0:7f98d386be37 513 break;
NicolasXu 0:7f98d386be37 514
NicolasXu 0:7f98d386be37 515 case slope:
NicolasXu 0:7f98d386be37 516 /**
NicolasXu 0:7f98d386be37 517 algorithm to calculate the angle
NicolasXu 0:7f98d386be37 518 */
NicolasXu 0:7f98d386be37 519 char buffer5[14];
NicolasXu 0:7f98d386be37 520 length = sprintf(buffer5, "Slope");
NicolasXu 0:7f98d386be37 521 char buffer6[14];
NicolasXu 0:7f98d386be37 522 length = sprintf(buffer6, "x =%.2f pi", asin(acceleration.x)/3.1415926);
NicolasXu 0:7f98d386be37 523 char buffer7[14];
NicolasXu 0:7f98d386be37 524 length = sprintf(buffer7, "y =%.2f pi", asin(acceleration.y)/3.1415926);
NicolasXu 0:7f98d386be37 525 /**
NicolasXu 0:7f98d386be37 526 draw rectangle and print the data
NicolasXu 0:7f98d386be37 527 */
NicolasXu 0:7f98d386be37 528 lcd.drawRect(0,0,83,47,0);
NicolasXu 0:7f98d386be37 529 lcd.printString(buffer5,3,1);
NicolasXu 0:7f98d386be37 530 lcd.printString(buffer6,3,2);
NicolasXu 0:7f98d386be37 531 lcd.printString(buffer7,3,3);
NicolasXu 0:7f98d386be37 532 wait(0.1);
NicolasXu 0:7f98d386be37 533 lcd.clear();
NicolasXu 0:7f98d386be37 534
NicolasXu 0:7f98d386be37 535 /**
NicolasXu 0:7f98d386be37 536 determine if the device is perfect level
NicolasXu 0:7f98d386be37 537 when the acceleration on z-axis is greater than 0.95
NicolasXu 0:7f98d386be37 538 the LED will be turned on
NicolasXu 0:7f98d386be37 539 */
NicolasXu 0:7f98d386be37 540 if (acceleration.z > 0.95){
NicolasXu 0:7f98d386be37 541 led.write(1);
NicolasXu 0:7f98d386be37 542 }else
NicolasXu 0:7f98d386be37 543 led.write(0);
NicolasXu 0:7f98d386be37 544
NicolasXu 0:7f98d386be37 545 break;
NicolasXu 0:7f98d386be37 546
NicolasXu 0:7f98d386be37 547 }
NicolasXu 0:7f98d386be37 548
NicolasXu 0:7f98d386be37 549 }
NicolasXu 0:7f98d386be37 550
NicolasXu 0:7f98d386be37 551 }