This project allows for the sending of MIDI messages, and setting of variable resistances, controlled by a distance sensor. MIDI input messages can also be used to set the variable resistance.
Dependencies: N5110 PinDetect SRF08 USBDevice mbed PowerControl
main.cpp@1:802453187acf, 2015-05-11 (annotated)
- Committer:
- el13tjoc
- Date:
- Mon May 11 11:14:59 2015 +0000
- Revision:
- 1:802453187acf
- Parent:
- 0:39399720eaeb
Added Ethernet Powerdown;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
el13tjoc | 0:39399720eaeb | 1 | /** |
el13tjoc | 0:39399720eaeb | 2 | @file main.cpp |
el13tjoc | 0:39399720eaeb | 3 | |
el13tjoc | 0:39399720eaeb | 4 | @brief Program implementation |
el13tjoc | 0:39399720eaeb | 5 | |
el13tjoc | 0:39399720eaeb | 6 | */ |
el13tjoc | 0:39399720eaeb | 7 | #include "main.h" |
el13tjoc | 0:39399720eaeb | 8 | |
el13tjoc | 0:39399720eaeb | 9 | int main() { |
el13tjoc | 0:39399720eaeb | 10 | |
el13tjoc | 1:802453187acf | 11 | ///Powerdown the Ethernet peripheral |
el13tjoc | 1:802453187acf | 12 | PHY_PowerDown(); |
el13tjoc | 1:802453187acf | 13 | |
el13tjoc | 0:39399720eaeb | 14 | ///Read parameter variables from VALS.csv |
el13tjoc | 0:39399720eaeb | 15 | readNumberValuesFromFile(); |
el13tjoc | 0:39399720eaeb | 16 | ///Resise the smoothing values vector |
el13tjoc | 0:39399720eaeb | 17 | smoothingValues.resize(numberValues[distanceSmoothing]+1); |
el13tjoc | 0:39399720eaeb | 18 | |
el13tjoc | 0:39399720eaeb | 19 | ///Set MCP4151 chip select high initially |
el13tjoc | 0:39399720eaeb | 20 | CS = 1; |
el13tjoc | 0:39399720eaeb | 21 | /// Set the MCP4151 SPI for 16 bit mode 3 |
el13tjoc | 0:39399720eaeb | 22 | MCP4151.format(16,3); |
el13tjoc | 0:39399720eaeb | 23 | /// Set MCP4151 clock frequency to 1000000 |
el13tjoc | 0:39399720eaeb | 24 | MCP4151.frequency(1000000); |
el13tjoc | 0:39399720eaeb | 25 | |
el13tjoc | 0:39399720eaeb | 26 | ///Initialise the screen and print splash screen |
el13tjoc | 0:39399720eaeb | 27 | lcd.init(); |
el13tjoc | 0:39399720eaeb | 28 | lcd.printString("EXPRESSIONATOR",0,1); |
el13tjoc | 0:39399720eaeb | 29 | lcd.printString("version 1.0",0,2); |
el13tjoc | 0:39399720eaeb | 30 | lcd.printString("Toby O'Connell",0,4); |
el13tjoc | 1:802453187acf | 31 | wait(3); |
el13tjoc | 0:39399720eaeb | 32 | |
el13tjoc | 0:39399720eaeb | 33 | ///Setup callback function for range finder ticker |
el13tjoc | 0:39399720eaeb | 34 | startRangingTicker.attach(&startRangingFlag, 0.1); |
el13tjoc | 0:39399720eaeb | 35 | |
el13tjoc | 0:39399720eaeb | 36 | ///Set the initial range finder distance |
el13tjoc | 0:39399720eaeb | 37 | SRF08.setRangeRegister((int)((numberValues[maxDistance]-43.0)/43.0)); |
el13tjoc | 0:39399720eaeb | 38 | |
el13tjoc | 0:39399720eaeb | 39 | ///Setup callback function for when MIDI messages are received |
el13tjoc | 0:39399720eaeb | 40 | midi.attach(receivedMIDI); |
el13tjoc | 0:39399720eaeb | 41 | |
el13tjoc | 0:39399720eaeb | 42 | ///Setup callbacks functions for button presses |
el13tjoc | 0:39399720eaeb | 43 | buttonA.attach_asserted(&aPressed); //Attach functions to button presses |
el13tjoc | 0:39399720eaeb | 44 | buttonB.attach_asserted(&bPressed); |
el13tjoc | 0:39399720eaeb | 45 | buttonC.attach_asserted(&cPressed); |
el13tjoc | 0:39399720eaeb | 46 | buttonD.attach_asserted(&dPressed); |
el13tjoc | 0:39399720eaeb | 47 | |
el13tjoc | 0:39399720eaeb | 48 | ///Set button press doubounce freqencies to the default of 20ms |
el13tjoc | 0:39399720eaeb | 49 | buttonA.setSampleFrequency(); |
el13tjoc | 0:39399720eaeb | 50 | buttonB.setSampleFrequency(); |
el13tjoc | 0:39399720eaeb | 51 | buttonC.setSampleFrequency(); |
el13tjoc | 0:39399720eaeb | 52 | buttonD.setSampleFrequency(); |
el13tjoc | 0:39399720eaeb | 53 | |
el13tjoc | 0:39399720eaeb | 54 | ///Open the buttons.bmp image in binary, skip the header and copy into a buffer before closing |
el13tjoc | 0:39399720eaeb | 55 | img = fopen("/local/BUTTONS.BMP", "rb"); |
el13tjoc | 0:39399720eaeb | 56 | fseek (img , 54 , SEEK_SET); |
el13tjoc | 0:39399720eaeb | 57 | fread(imgbuffer, (84*3*48), 1, img); |
el13tjoc | 0:39399720eaeb | 58 | fclose(img); |
el13tjoc | 0:39399720eaeb | 59 | |
el13tjoc | 0:39399720eaeb | 60 | ///Show initial menu |
el13tjoc | 0:39399720eaeb | 61 | showScreen(); |
el13tjoc | 0:39399720eaeb | 62 | ///Create infinite while loop to run program repeatedly |
el13tjoc | 0:39399720eaeb | 63 | while(1) { |
el13tjoc | 0:39399720eaeb | 64 | if(aButtonFlag){ |
el13tjoc | 0:39399720eaeb | 65 | if (menu[state].screenType == menuType || digitArrowPosition + 1 >= maxValLen) { |
el13tjoc | 0:39399720eaeb | 66 | ///screenSelect() if button A is pressed and the screen type is a menu or a page type that is confirmed |
el13tjoc | 0:39399720eaeb | 67 | screenSelect(); |
el13tjoc | 0:39399720eaeb | 68 | } else { |
el13tjoc | 0:39399720eaeb | 69 | ///incrementDigitArrowPos() if button A is pressed and the screen type is not a menu or a page type that is confirmed |
el13tjoc | 0:39399720eaeb | 70 | incrementDigitArrowPos(); |
el13tjoc | 0:39399720eaeb | 71 | } |
el13tjoc | 0:39399720eaeb | 72 | aButtonFlag = 0; |
el13tjoc | 0:39399720eaeb | 73 | } |
el13tjoc | 0:39399720eaeb | 74 | if(bButtonFlag){ |
el13tjoc | 0:39399720eaeb | 75 | if (menu[state].screenType == menuType || digitArrowPosition - 1 < 0) { |
el13tjoc | 0:39399720eaeb | 76 | ///screenBack() if button B is pressed and the screen type is a menu or a page type that is reverted |
el13tjoc | 0:39399720eaeb | 77 | screenBack(); |
el13tjoc | 0:39399720eaeb | 78 | } else { |
el13tjoc | 0:39399720eaeb | 79 | ///decrementDigitArrowPos() if button B is pressed and the screen type is not a menu or a page type that is confirmed |
el13tjoc | 0:39399720eaeb | 80 | decrementDigitArrowPos(); |
el13tjoc | 0:39399720eaeb | 81 | } |
el13tjoc | 0:39399720eaeb | 82 | bButtonFlag = 0; |
el13tjoc | 0:39399720eaeb | 83 | } |
el13tjoc | 0:39399720eaeb | 84 | if(cButtonFlag){ |
el13tjoc | 0:39399720eaeb | 85 | if (menu[state].screenType == menuType) { |
el13tjoc | 0:39399720eaeb | 86 | ///menuUp() if button C is pressed and the screen type is a menu |
el13tjoc | 0:39399720eaeb | 87 | menuUp(); |
el13tjoc | 0:39399720eaeb | 88 | } else { |
el13tjoc | 0:39399720eaeb | 89 | ///incrementValue() if button C is pressed and the screen type is not a menu |
el13tjoc | 0:39399720eaeb | 90 | incrementValue(); |
el13tjoc | 0:39399720eaeb | 91 | } |
el13tjoc | 0:39399720eaeb | 92 | cButtonFlag = 0; |
el13tjoc | 0:39399720eaeb | 93 | } |
el13tjoc | 0:39399720eaeb | 94 | if(dButtonFlag){ |
el13tjoc | 0:39399720eaeb | 95 | if (menu[state].screenType == menuType) { |
el13tjoc | 0:39399720eaeb | 96 | ///menuDown() if button D is pressed and the screen type is a menu |
el13tjoc | 0:39399720eaeb | 97 | menuDown(); |
el13tjoc | 0:39399720eaeb | 98 | } else { |
el13tjoc | 0:39399720eaeb | 99 | ///decrementValue() if button D is pressed and the screen type is not a menu |
el13tjoc | 0:39399720eaeb | 100 | decrementValue(); |
el13tjoc | 0:39399720eaeb | 101 | } |
el13tjoc | 0:39399720eaeb | 102 | dButtonFlag = 0; |
el13tjoc | 0:39399720eaeb | 103 | } |
el13tjoc | 0:39399720eaeb | 104 | if(rangingStartFlag) { |
el13tjoc | 0:39399720eaeb | 105 | ///Start ranging if the startRangingTicker has fired |
el13tjoc | 0:39399720eaeb | 106 | rangingStart(); |
el13tjoc | 0:39399720eaeb | 107 | rangingStartFlag = 0; |
el13tjoc | 0:39399720eaeb | 108 | } |
el13tjoc | 0:39399720eaeb | 109 | if(rangeGetFlag) { |
el13tjoc | 0:39399720eaeb | 110 | ///Start ranging if the getRangeTimeout has fired |
el13tjoc | 0:39399720eaeb | 111 | rangeGet(); |
el13tjoc | 0:39399720eaeb | 112 | rangeGetFlag = 0; |
el13tjoc | 0:39399720eaeb | 113 | } |
el13tjoc | 0:39399720eaeb | 114 | if(measuredDistanceFlag) { |
el13tjoc | 0:39399720eaeb | 115 | if(numberValues[MIDIOutputOn]) { |
el13tjoc | 0:39399720eaeb | 116 | ///writeMIDI() if the distance has just been measured and MIDI output is on |
el13tjoc | 0:39399720eaeb | 117 | writeMIDI(distanceFraction); |
el13tjoc | 0:39399720eaeb | 118 | } |
el13tjoc | 0:39399720eaeb | 119 | if(numberValues[resistanceSourceIndex] == sensorSource) { |
el13tjoc | 0:39399720eaeb | 120 | ///writeMCP4151() if the distance has just been measured and the resistance source is the ultrasonic sensor |
el13tjoc | 0:39399720eaeb | 121 | writeMCP4151(distanceFraction); |
el13tjoc | 0:39399720eaeb | 122 | } |
el13tjoc | 0:39399720eaeb | 123 | ///showScreen() if the distance has just been measured and the screen type is the display screen |
el13tjoc | 0:39399720eaeb | 124 | if(menu[state].screenType == displayType) showScreen(); |
el13tjoc | 0:39399720eaeb | 125 | measuredDistanceFlag = 0; |
el13tjoc | 0:39399720eaeb | 126 | } |
el13tjoc | 0:39399720eaeb | 127 | if(receivedMIDIFlag) { |
el13tjoc | 0:39399720eaeb | 128 | if(numberValues[resistanceSourceIndex] == MIDISource) { |
el13tjoc | 0:39399720eaeb | 129 | ///writeMCP4151() if a MIDI message has been received and the resistance source is the MIDI input |
el13tjoc | 0:39399720eaeb | 130 | writeMCP4151(receivedMIDIValue/127.0); |
el13tjoc | 0:39399720eaeb | 131 | } |
el13tjoc | 0:39399720eaeb | 132 | ///showScreen() if a MIDI message has been received and the screen type is the display screen |
el13tjoc | 0:39399720eaeb | 133 | if(menu[state].screenType == displayType) showScreen(); |
el13tjoc | 0:39399720eaeb | 134 | receivedMIDIFlag = 0; |
el13tjoc | 0:39399720eaeb | 135 | } |
el13tjoc | 0:39399720eaeb | 136 | } |
el13tjoc | 0:39399720eaeb | 137 | } |
el13tjoc | 0:39399720eaeb | 138 | |
el13tjoc | 0:39399720eaeb | 139 | |
el13tjoc | 0:39399720eaeb | 140 | void aPressed() { aButtonFlag = 1; } //raise button flags |
el13tjoc | 0:39399720eaeb | 141 | void bPressed() { bButtonFlag = 1; } |
el13tjoc | 0:39399720eaeb | 142 | void cPressed() { cButtonFlag = 1; } |
el13tjoc | 0:39399720eaeb | 143 | void dPressed() { dButtonFlag = 1; } |
el13tjoc | 0:39399720eaeb | 144 | |
el13tjoc | 0:39399720eaeb | 145 | void startRangingFlag() { rangingStartFlag = 1;} //raise ranging star flag |
el13tjoc | 0:39399720eaeb | 146 | void getRangeFlag() { rangeGetFlag = 1;} //raise range get flag |
el13tjoc | 0:39399720eaeb | 147 | |
el13tjoc | 0:39399720eaeb | 148 | void screenSelect() { |
el13tjoc | 0:39399720eaeb | 149 | if (menu[state].screenType == pageType) { |
el13tjoc | 0:39399720eaeb | 150 | ///If exiting a page type screen checkValidity() and do the immediateUpdates() |
el13tjoc | 0:39399720eaeb | 151 | checkValidity(); |
el13tjoc | 0:39399720eaeb | 152 | writeNumberValuesToFile(); |
el13tjoc | 0:39399720eaeb | 153 | immediateUpdates(); |
el13tjoc | 0:39399720eaeb | 154 | } |
el13tjoc | 0:39399720eaeb | 155 | ///Change to the next state based on the menu arrow position |
el13tjoc | 0:39399720eaeb | 156 | state = menu[state].nextState[menuArrowPosition]; //Set new menu state basted on arrow position |
el13tjoc | 0:39399720eaeb | 157 | if (menu[state].screenType == pageType) { |
el13tjoc | 0:39399720eaeb | 158 | ///if entering a page type screen save the associated value to oldValue for reverting back |
el13tjoc | 0:39399720eaeb | 159 | oldValue = numberValues[menu[state].associatedValueIndex]; |
el13tjoc | 0:39399720eaeb | 160 | } |
el13tjoc | 0:39399720eaeb | 161 | ///Reset menu and digit arrow posiitons |
el13tjoc | 0:39399720eaeb | 162 | menuArrowPosition = 0; |
el13tjoc | 0:39399720eaeb | 163 | digitArrowPosition = 0; |
el13tjoc | 0:39399720eaeb | 164 | ///Update the display |
el13tjoc | 0:39399720eaeb | 165 | showScreen(); |
el13tjoc | 0:39399720eaeb | 166 | } |
el13tjoc | 0:39399720eaeb | 167 | void screenBack() { |
el13tjoc | 0:39399720eaeb | 168 | if (menu[state].screenType == pageType) { |
el13tjoc | 0:39399720eaeb | 169 | ///If reverting back out of a page type screen set the assoicated value to its previous value |
el13tjoc | 0:39399720eaeb | 170 | numberValues[menu[state].associatedValueIndex] = oldValue; |
el13tjoc | 0:39399720eaeb | 171 | } |
el13tjoc | 0:39399720eaeb | 172 | ///Go to FSM parent state |
el13tjoc | 0:39399720eaeb | 173 | state = menu[state].previousState; |
el13tjoc | 0:39399720eaeb | 174 | ///Reset menu and digit arrow posiitons |
el13tjoc | 0:39399720eaeb | 175 | menuArrowPosition = 0; |
el13tjoc | 0:39399720eaeb | 176 | digitArrowPosition = 0; |
el13tjoc | 0:39399720eaeb | 177 | ///Update the display |
el13tjoc | 0:39399720eaeb | 178 | showScreen(); |
el13tjoc | 0:39399720eaeb | 179 | } |
el13tjoc | 0:39399720eaeb | 180 | void menuUp() { |
el13tjoc | 0:39399720eaeb | 181 | ///Decrement the menu arrow position |
el13tjoc | 0:39399720eaeb | 182 | menuArrowPosition = (menuArrowPosition + menu[state].listLength - 1) % menu[state].listLength; |
el13tjoc | 0:39399720eaeb | 183 | ///Update the display |
el13tjoc | 0:39399720eaeb | 184 | showScreen(); |
el13tjoc | 0:39399720eaeb | 185 | } |
el13tjoc | 0:39399720eaeb | 186 | void menuDown() { |
el13tjoc | 0:39399720eaeb | 187 | ///Increment the menu arrow position |
el13tjoc | 0:39399720eaeb | 188 | menuArrowPosition = (menuArrowPosition + 1) % menu[state].listLength; |
el13tjoc | 0:39399720eaeb | 189 | ///Update the display |
el13tjoc | 0:39399720eaeb | 190 | showScreen(); |
el13tjoc | 0:39399720eaeb | 191 | } |
el13tjoc | 0:39399720eaeb | 192 | |
el13tjoc | 0:39399720eaeb | 193 | void incrementDigitArrowPos() { |
el13tjoc | 0:39399720eaeb | 194 | ///Increment the digit arrow position |
el13tjoc | 0:39399720eaeb | 195 | digitArrowPosition += 1; |
el13tjoc | 0:39399720eaeb | 196 | ///Update the display |
el13tjoc | 0:39399720eaeb | 197 | showScreen(); |
el13tjoc | 0:39399720eaeb | 198 | } |
el13tjoc | 0:39399720eaeb | 199 | void decrementDigitArrowPos() { |
el13tjoc | 0:39399720eaeb | 200 | ///Increment the digit arrow position |
el13tjoc | 0:39399720eaeb | 201 | digitArrowPosition -= 1; |
el13tjoc | 0:39399720eaeb | 202 | ///Update the display |
el13tjoc | 0:39399720eaeb | 203 | showScreen(); |
el13tjoc | 0:39399720eaeb | 204 | } |
el13tjoc | 0:39399720eaeb | 205 | |
el13tjoc | 0:39399720eaeb | 206 | void incrementValue() { |
el13tjoc | 0:39399720eaeb | 207 | ///Set the increment to '1' |
el13tjoc | 0:39399720eaeb | 208 | increment = 1; |
el13tjoc | 0:39399720eaeb | 209 | ///amend the value |
el13tjoc | 0:39399720eaeb | 210 | amendValue(); |
el13tjoc | 0:39399720eaeb | 211 | } |
el13tjoc | 0:39399720eaeb | 212 | |
el13tjoc | 0:39399720eaeb | 213 | void decrementValue() { |
el13tjoc | 0:39399720eaeb | 214 | ///Set the increment to '-1' |
el13tjoc | 0:39399720eaeb | 215 | increment = -1; |
el13tjoc | 0:39399720eaeb | 216 | ///amend the value |
el13tjoc | 0:39399720eaeb | 217 | amendValue(); |
el13tjoc | 0:39399720eaeb | 218 | } |
el13tjoc | 0:39399720eaeb | 219 | |
el13tjoc | 0:39399720eaeb | 220 | int amendNumberValue(int value) { |
el13tjoc | 0:39399720eaeb | 221 | ///Get the digit at the current arrow position |
el13tjoc | 0:39399720eaeb | 222 | int currentDigit = (int)(value / pow(10.0,maxValLen-1-digitArrowPosition))%10; |
el13tjoc | 0:39399720eaeb | 223 | |
el13tjoc | 0:39399720eaeb | 224 | if((currentDigit == 9 && increment == + 1) || (currentDigit == 0 && increment == - 1)) { |
el13tjoc | 0:39399720eaeb | 225 | ///If the digit is will become greater than 9 or less then 0, wrap around |
el13tjoc | 0:39399720eaeb | 226 | value = value - increment * 9 * pow(10.0,maxValLen-1-digitArrowPosition); |
el13tjoc | 0:39399720eaeb | 227 | } else { |
el13tjoc | 0:39399720eaeb | 228 | ///If not, increment / decrement the value |
el13tjoc | 0:39399720eaeb | 229 | value = value + increment * pow(10.0,maxValLen-1-digitArrowPosition); |
el13tjoc | 0:39399720eaeb | 230 | } |
el13tjoc | 0:39399720eaeb | 231 | |
el13tjoc | 0:39399720eaeb | 232 | ///return the value |
el13tjoc | 0:39399720eaeb | 233 | return value; |
el13tjoc | 0:39399720eaeb | 234 | } |
el13tjoc | 0:39399720eaeb | 235 | |
el13tjoc | 0:39399720eaeb | 236 | void amendValue() { |
el13tjoc | 0:39399720eaeb | 237 | |
el13tjoc | 0:39399720eaeb | 238 | switch(menu[state].associatedValueType) { |
el13tjoc | 0:39399720eaeb | 239 | case INT: |
el13tjoc | 0:39399720eaeb | 240 | ///If the associated is an int style number amendNumberValue() |
el13tjoc | 0:39399720eaeb | 241 | numberValues[menu[state].associatedValueIndex] = amendNumberValue(numberValues[menu[state].associatedValueIndex]); |
el13tjoc | 0:39399720eaeb | 242 | break; |
el13tjoc | 0:39399720eaeb | 243 | case INDEX: |
el13tjoc | 0:39399720eaeb | 244 | ///If the associated is an index style number increment / decrement it |
el13tjoc | 0:39399720eaeb | 245 | numberValues[menu[state].associatedValueIndex] = (maxNumberValues[menu[state].associatedMaxValueIndex] + numberValues[menu[state].associatedValueIndex] + increment) % maxNumberValues[menu[state].associatedMaxValueIndex]; |
el13tjoc | 0:39399720eaeb | 246 | break; |
el13tjoc | 0:39399720eaeb | 247 | case BOOL: |
el13tjoc | 0:39399720eaeb | 248 | ///If the associated is a boolean style number invert it |
el13tjoc | 0:39399720eaeb | 249 | numberValues[menu[state].associatedValueIndex] = !numberValues[menu[state].associatedValueIndex]; |
el13tjoc | 0:39399720eaeb | 250 | break; |
el13tjoc | 0:39399720eaeb | 251 | } |
el13tjoc | 0:39399720eaeb | 252 | ///Update the display |
el13tjoc | 0:39399720eaeb | 253 | showScreen(); |
el13tjoc | 0:39399720eaeb | 254 | } |
el13tjoc | 0:39399720eaeb | 255 | |
el13tjoc | 0:39399720eaeb | 256 | |
el13tjoc | 0:39399720eaeb | 257 | |
el13tjoc | 0:39399720eaeb | 258 | void showScreen() { |
el13tjoc | 0:39399720eaeb | 259 | ///Clear the screen |
el13tjoc | 0:39399720eaeb | 260 | lcd.clear(); |
el13tjoc | 0:39399720eaeb | 261 | ///Show the title |
el13tjoc | 0:39399720eaeb | 262 | lcd.printString(menu[state].title,0,0); |
el13tjoc | 0:39399720eaeb | 263 | if(menu[state].screenType == menuType) { |
el13tjoc | 0:39399720eaeb | 264 | for (int i = 0;i <= 3; i++) { |
el13tjoc | 0:39399720eaeb | 265 | ///If the screen type is a menu, print the items in its list |
el13tjoc | 0:39399720eaeb | 266 | lcd.printString(menu[state].list[i],6,i+1); |
el13tjoc | 0:39399720eaeb | 267 | } |
el13tjoc | 0:39399720eaeb | 268 | if(menu[state].listLength > 0) { |
el13tjoc | 0:39399720eaeb | 269 | ///if the list has items in it, then show show the menu arrow pointer |
el13tjoc | 0:39399720eaeb | 270 | lcd.printString(">",0,menuArrowPosition+1); |
el13tjoc | 0:39399720eaeb | 271 | } |
el13tjoc | 0:39399720eaeb | 272 | } else if(menu[state].screenType == pageType) { |
el13tjoc | 0:39399720eaeb | 273 | switch (menu[state].associatedValueType) { |
el13tjoc | 0:39399720eaeb | 274 | case INT: |
el13tjoc | 0:39399720eaeb | 275 | ///If the screen type is a parameter editing page and the associated value is an int type number, displayNumber() and show the digit arrow pointer |
el13tjoc | 0:39399720eaeb | 276 | displayNumber(numberValues[menu[state].associatedValueIndex],maxNumberValues[menu[state].associatedMaxValueIndex]); |
el13tjoc | 0:39399720eaeb | 277 | lcd.printString("^",digitArrowPosition*6+7,3); |
el13tjoc | 0:39399720eaeb | 278 | break; |
el13tjoc | 0:39399720eaeb | 279 | case INDEX: |
el13tjoc | 0:39399720eaeb | 280 | ///If the screen type is a parameter editing page and the associated value is an index type number, displayList() |
el13tjoc | 0:39399720eaeb | 281 | displayList(valueLists[menu[state].associatedValueList],numberValues[menu[state].associatedValueIndex]); |
el13tjoc | 0:39399720eaeb | 282 | break; |
el13tjoc | 0:39399720eaeb | 283 | case BOOL: |
el13tjoc | 0:39399720eaeb | 284 | ///If the screen type is a parameter editing page and the associated value is a boolean type number, displayBool() |
el13tjoc | 0:39399720eaeb | 285 | displayBool(numberValues[menu[state].associatedValueIndex]); |
el13tjoc | 0:39399720eaeb | 286 | break; |
el13tjoc | 0:39399720eaeb | 287 | } |
el13tjoc | 0:39399720eaeb | 288 | } else { |
el13tjoc | 0:39399720eaeb | 289 | ///If the screen type is the display screen, displayMeasured() |
el13tjoc | 0:39399720eaeb | 290 | displayMeasured(); |
el13tjoc | 0:39399720eaeb | 291 | } |
el13tjoc | 0:39399720eaeb | 292 | ///Draw the buttons.bmp image to the screen using drawBMP() |
el13tjoc | 0:39399720eaeb | 293 | drawBMP(); |
el13tjoc | 0:39399720eaeb | 294 | } |
el13tjoc | 0:39399720eaeb | 295 | |
el13tjoc | 0:39399720eaeb | 296 | void displayNumber(int value, int maxValue) { |
el13tjoc | 0:39399720eaeb | 297 | char buffer[14]; |
el13tjoc | 0:39399720eaeb | 298 | ///Find the maximum length the incoming value could be |
el13tjoc | 0:39399720eaeb | 299 | maxValLen = sprintf(buffer,"%d",maxValue); |
el13tjoc | 0:39399720eaeb | 300 | ///Find the actual length of the incoming value |
el13tjoc | 0:39399720eaeb | 301 | valLen = sprintf(buffer,"%d",value); |
el13tjoc | 0:39399720eaeb | 302 | ///Print the value to the screen, filling any unused digit spaces with zeros |
el13tjoc | 0:39399720eaeb | 303 | for(int i = 0; i <= maxValLen - valLen; i++) { |
el13tjoc | 0:39399720eaeb | 304 | lcd.printString("0",6*i+7,2); |
el13tjoc | 0:39399720eaeb | 305 | } |
el13tjoc | 0:39399720eaeb | 306 | lcd.printString(buffer,6*(maxValLen-valLen)+7,2); |
el13tjoc | 0:39399720eaeb | 307 | } |
el13tjoc | 0:39399720eaeb | 308 | |
el13tjoc | 0:39399720eaeb | 309 | void displayList(string list[], int listIndex) { |
el13tjoc | 0:39399720eaeb | 310 | char buffer[14]; |
el13tjoc | 0:39399720eaeb | 311 | maxValLen = 1; |
el13tjoc | 0:39399720eaeb | 312 | ///Display the list element at the list index |
el13tjoc | 0:39399720eaeb | 313 | valLen = sprintf(buffer,"%s",list[listIndex].c_str()); |
el13tjoc | 0:39399720eaeb | 314 | lcd.printString(buffer,7,2); |
el13tjoc | 0:39399720eaeb | 315 | } |
el13tjoc | 0:39399720eaeb | 316 | |
el13tjoc | 0:39399720eaeb | 317 | void displayBool(bool toggle) { |
el13tjoc | 0:39399720eaeb | 318 | char buffer[14]; |
el13tjoc | 0:39399720eaeb | 319 | maxValLen = 1; |
el13tjoc | 0:39399720eaeb | 320 | ///Print "On" if the boolean value is 1 and "Off" if the boolean value is 0 |
el13tjoc | 0:39399720eaeb | 321 | valLen = sprintf(buffer,"%s", toggle ? "On" : "Off"); |
el13tjoc | 0:39399720eaeb | 322 | lcd.printString(buffer,7,2); |
el13tjoc | 0:39399720eaeb | 323 | } |
el13tjoc | 0:39399720eaeb | 324 | |
el13tjoc | 0:39399720eaeb | 325 | void displayMeasured() { |
el13tjoc | 0:39399720eaeb | 326 | char buffer[14]; |
el13tjoc | 0:39399720eaeb | 327 | ///Print the distance measured by the SRF08 |
el13tjoc | 0:39399720eaeb | 328 | sprintf(buffer,"D: %d",measuredDistance); |
el13tjoc | 0:39399720eaeb | 329 | lcd.printString(buffer,7,1); |
el13tjoc | 0:39399720eaeb | 330 | ///If the MIDI output is on, print the MIDI output value, else print "OFF" |
el13tjoc | 0:39399720eaeb | 331 | if(numberValues[MIDIOutputOn] == 1) { |
el13tjoc | 0:39399720eaeb | 332 | sprintf(buffer,"MO: %d",(int)(distanceFraction*127)); |
el13tjoc | 0:39399720eaeb | 333 | } else { |
el13tjoc | 0:39399720eaeb | 334 | sprintf(buffer,"MO: OFF"); |
el13tjoc | 0:39399720eaeb | 335 | } |
el13tjoc | 0:39399720eaeb | 336 | lcd.printString(buffer,7,2); |
el13tjoc | 0:39399720eaeb | 337 | ///Print the input MIDI value |
el13tjoc | 0:39399720eaeb | 338 | sprintf(buffer,"MI: %d",receivedMIDIValue); |
el13tjoc | 0:39399720eaeb | 339 | lcd.printString(buffer,7,3); |
el13tjoc | 0:39399720eaeb | 340 | if(numberValues[resistanceSourceIndex] == sensorSource) { |
el13tjoc | 0:39399720eaeb | 341 | ///If the resistance source is the SRF08, print the resistance based on that distance |
el13tjoc | 0:39399720eaeb | 342 | sprintf(buffer,"R: %d",(int)(numberValues[minResistance]+distanceFraction*(numberValues[maxResistance]-numberValues[minResistance]))); |
el13tjoc | 0:39399720eaeb | 343 | } else if(numberValues[resistanceSourceIndex] == MIDISource) { |
el13tjoc | 0:39399720eaeb | 344 | ///If the resistance source is the the MIDI input, print the resistance based on the MIDI value |
el13tjoc | 0:39399720eaeb | 345 | sprintf(buffer,"R: %d",(int)(numberValues[minResistance]+(receivedMIDIValue/127.0)*(numberValues[maxResistance]-numberValues[minResistance]))); |
el13tjoc | 0:39399720eaeb | 346 | } else { |
el13tjoc | 0:39399720eaeb | 347 | ///If the resistance source is set to OFF, print "OFF" |
el13tjoc | 0:39399720eaeb | 348 | sprintf(buffer,"R: OFF"); |
el13tjoc | 0:39399720eaeb | 349 | } |
el13tjoc | 0:39399720eaeb | 350 | lcd.printString(buffer,7,4); |
el13tjoc | 0:39399720eaeb | 351 | } |
el13tjoc | 0:39399720eaeb | 352 | |
el13tjoc | 0:39399720eaeb | 353 | void rangingStart() { |
el13tjoc | 0:39399720eaeb | 354 | ///detach the getRangeTimeout |
el13tjoc | 0:39399720eaeb | 355 | getRangeTimeout.detach(); |
el13tjoc | 0:39399720eaeb | 356 | ///start the SRF08 ranging |
el13tjoc | 0:39399720eaeb | 357 | SRF08.startRanging(CM); |
el13tjoc | 0:39399720eaeb | 358 | ///reattach the getRangeTimeout |
el13tjoc | 0:39399720eaeb | 359 | getRangeTimeout.attach(&getRangeFlag,0.07); |
el13tjoc | 0:39399720eaeb | 360 | } |
el13tjoc | 0:39399720eaeb | 361 | |
el13tjoc | 0:39399720eaeb | 362 | void rangeGet() { |
el13tjoc | 0:39399720eaeb | 363 | ///Get the measured distance from the SRF08 |
el13tjoc | 0:39399720eaeb | 364 | measuredDistance = SRF08.getRange(); |
el13tjoc | 0:39399720eaeb | 365 | //Convert the measuredDistance to a float between 0 and 1 |
el13tjoc | 0:39399720eaeb | 366 | distanceFraction = (measuredDistance * 10 - numberValues[minDistance]) / (float)(numberValues[maxDistance]-numberValues[minDistance]); |
el13tjoc | 0:39399720eaeb | 367 | ///If the distanceFraction is > 1 or < 0, limit it to 1 or 0 |
el13tjoc | 0:39399720eaeb | 368 | if(distanceFraction > 1) distanceFraction = 1; |
el13tjoc | 0:39399720eaeb | 369 | if(distanceFraction < 0) distanceFraction = 0; |
el13tjoc | 0:39399720eaeb | 370 | ///smooth() the distance fraction |
el13tjoc | 0:39399720eaeb | 371 | distanceFraction = smooth(distanceFraction); |
el13tjoc | 0:39399720eaeb | 372 | measuredDistanceFlag = 1; |
el13tjoc | 0:39399720eaeb | 373 | } |
el13tjoc | 0:39399720eaeb | 374 | |
el13tjoc | 0:39399720eaeb | 375 | void receivedMIDI(MIDIMessage msg) { |
el13tjoc | 0:39399720eaeb | 376 | if(msg.type() == MIDIMessage::ControlChangeType && msg.controller() == numberValues[MIDIInputController] && msg.channel() == numberValues[MIDIInputChannel]) { |
el13tjoc | 0:39399720eaeb | 377 | ///If the MIDI message is the right controller change on the right channel, save the value |
el13tjoc | 0:39399720eaeb | 378 | receivedMIDIValue = msg.value(); |
el13tjoc | 0:39399720eaeb | 379 | receivedMIDIFlag = 1; |
el13tjoc | 0:39399720eaeb | 380 | } |
el13tjoc | 0:39399720eaeb | 381 | } |
el13tjoc | 0:39399720eaeb | 382 | |
el13tjoc | 0:39399720eaeb | 383 | |
el13tjoc | 0:39399720eaeb | 384 | float smooth(float value) { |
el13tjoc | 0:39399720eaeb | 385 | ///Erase the first element in the smoothing vector |
el13tjoc | 0:39399720eaeb | 386 | smoothingValues.erase(smoothingValues.begin()); |
el13tjoc | 0:39399720eaeb | 387 | ///Add the value to the end of the smoothing vector |
el13tjoc | 0:39399720eaeb | 388 | smoothingValues.push_back(value); |
el13tjoc | 0:39399720eaeb | 389 | ///Sum the values in the smoothing vector |
el13tjoc | 0:39399720eaeb | 390 | float sum = 0; |
el13tjoc | 0:39399720eaeb | 391 | for(int i = 0; i < smoothingValues.size(); i++) { |
el13tjoc | 0:39399720eaeb | 392 | sum += smoothingValues[i]; |
el13tjoc | 0:39399720eaeb | 393 | } |
el13tjoc | 0:39399720eaeb | 394 | ///Return the mean average of the smoothing vector contents |
el13tjoc | 0:39399720eaeb | 395 | return sum/(smoothingValues.size()); |
el13tjoc | 0:39399720eaeb | 396 | } |
el13tjoc | 0:39399720eaeb | 397 | |
el13tjoc | 0:39399720eaeb | 398 | |
el13tjoc | 0:39399720eaeb | 399 | |
el13tjoc | 0:39399720eaeb | 400 | void writeMCP4151(float value) { |
el13tjoc | 0:39399720eaeb | 401 | ///Scale the max and min resistances for 0 to 10000 down to 0 to 255. |
el13tjoc | 0:39399720eaeb | 402 | int scaledMax = (int)(numberValues[maxResistance]/(10000/255.0)); |
el13tjoc | 0:39399720eaeb | 403 | int scaledMin = (int)(numberValues[minResistance]/(10000/255.0)); |
el13tjoc | 0:39399720eaeb | 404 | ///Convert the 0 to 1 float value to a 0 to 255 int value for the MCP4151 SPI digital potentiometer |
el13tjoc | 0:39399720eaeb | 405 | int writeValue = (int)(1 + scaledMin + value * (scaledMax - scaledMin)); |
el13tjoc | 0:39399720eaeb | 406 | ///Chip enable |
el13tjoc | 0:39399720eaeb | 407 | CS = 0; |
el13tjoc | 0:39399720eaeb | 408 | ///Write the new value |
el13tjoc | 0:39399720eaeb | 409 | MCP4151.write(writeValue); |
el13tjoc | 0:39399720eaeb | 410 | ///Chip disable |
el13tjoc | 0:39399720eaeb | 411 | CS = 1; |
el13tjoc | 0:39399720eaeb | 412 | } |
el13tjoc | 0:39399720eaeb | 413 | |
el13tjoc | 0:39399720eaeb | 414 | void writeMIDI(float value) { |
el13tjoc | 0:39399720eaeb | 415 | ///Convert the 0 to 1 float valye to 0 to 127 int value for the MIDI message |
el13tjoc | 0:39399720eaeb | 416 | int writeValue = (int)(value * 127); |
el13tjoc | 0:39399720eaeb | 417 | ///Write the 0 to 255 value to the MIDI output |
el13tjoc | 0:39399720eaeb | 418 | midi.write(MIDIMessage::ControlChange(numberValues[MIDIOutputController],writeValue,numberValues[MIDIOutputChannel])); |
el13tjoc | 0:39399720eaeb | 419 | } |
el13tjoc | 0:39399720eaeb | 420 | |
el13tjoc | 0:39399720eaeb | 421 | void drawBMP() { |
el13tjoc | 0:39399720eaeb | 422 | ///Iterate through each pixel in the image buffer |
el13tjoc | 0:39399720eaeb | 423 | for (int i = 0; i < 84*48 ; i++) { |
el13tjoc | 0:39399720eaeb | 424 | if (imgbuffer[i*3] == 0) { |
el13tjoc | 0:39399720eaeb | 425 | ///If the pixel is not white, write it to the screen |
el13tjoc | 0:39399720eaeb | 426 | lcd.setPixel(i%84,47-(int)(i/84)); |
el13tjoc | 0:39399720eaeb | 427 | } |
el13tjoc | 0:39399720eaeb | 428 | } |
el13tjoc | 0:39399720eaeb | 429 | lcd.refresh(); |
el13tjoc | 0:39399720eaeb | 430 | } |
el13tjoc | 0:39399720eaeb | 431 | |
el13tjoc | 0:39399720eaeb | 432 | void readNumberValuesFromFile() { |
el13tjoc | 0:39399720eaeb | 433 | ///Open the VALS.csv file |
el13tjoc | 0:39399720eaeb | 434 | ifstream csvValuesRead("/local/VALS.csv"); |
el13tjoc | 0:39399720eaeb | 435 | for(int i = 0; i < 11; i++) { |
el13tjoc | 0:39399720eaeb | 436 | ///Copy each line of the csv file to a each element in the numberValues array |
el13tjoc | 0:39399720eaeb | 437 | string line; |
el13tjoc | 0:39399720eaeb | 438 | getline(csvValuesRead, line); |
el13tjoc | 0:39399720eaeb | 439 | stringstream convertor(line); |
el13tjoc | 0:39399720eaeb | 440 | convertor >> numberValues[i]; |
el13tjoc | 0:39399720eaeb | 441 | } |
el13tjoc | 0:39399720eaeb | 442 | ///Close the VALS.csv file |
el13tjoc | 0:39399720eaeb | 443 | csvValuesRead.close(); |
el13tjoc | 0:39399720eaeb | 444 | } |
el13tjoc | 0:39399720eaeb | 445 | |
el13tjoc | 0:39399720eaeb | 446 | void writeNumberValuesToFile() { |
el13tjoc | 0:39399720eaeb | 447 | ///Open the VALS.csv file |
el13tjoc | 0:39399720eaeb | 448 | FILE *csvValuesWrite = fopen("/local/VALS.csv","w"); |
el13tjoc | 0:39399720eaeb | 449 | for(int i = 0; i < 11; i++) { |
el13tjoc | 0:39399720eaeb | 450 | ///Write each element in the numberValues array to each line in the csv file |
el13tjoc | 0:39399720eaeb | 451 | fprintf(csvValuesWrite,"%d\n",numberValues[i]); |
el13tjoc | 0:39399720eaeb | 452 | } |
el13tjoc | 0:39399720eaeb | 453 | ///Close the VALS.csv file |
el13tjoc | 0:39399720eaeb | 454 | fclose(csvValuesWrite); |
el13tjoc | 0:39399720eaeb | 455 | } |
el13tjoc | 0:39399720eaeb | 456 | |
el13tjoc | 0:39399720eaeb | 457 | void checkValidity() { |
el13tjoc | 0:39399720eaeb | 458 | if(numberValues[menu[state].associatedValueIndex] > maxNumberValues[menu[state].associatedMaxValueIndex]) { |
el13tjoc | 0:39399720eaeb | 459 | ///If the associated value is greater than the associated max value after being altered, revert back to the original |
el13tjoc | 0:39399720eaeb | 460 | numberValues[menu[state].associatedValueIndex] = oldValue; |
el13tjoc | 0:39399720eaeb | 461 | } |
el13tjoc | 0:39399720eaeb | 462 | if(numberValues[minResistance] >= numberValues[maxResistance]) { |
el13tjoc | 0:39399720eaeb | 463 | if(menu[state].associatedValueIndex == minResistance) { |
el13tjoc | 0:39399720eaeb | 464 | ///If the min resistance is greater than the max resistance make it 1 less than the maximum |
el13tjoc | 0:39399720eaeb | 465 | numberValues[minResistance] = numberValues[maxResistance] - 1; |
el13tjoc | 0:39399720eaeb | 466 | } else { |
el13tjoc | 0:39399720eaeb | 467 | ///If the max resistance is less than the max resistance make it 1 more than the minimum |
el13tjoc | 0:39399720eaeb | 468 | numberValues[maxResistance] = numberValues[minResistance] + 1; |
el13tjoc | 0:39399720eaeb | 469 | } |
el13tjoc | 0:39399720eaeb | 470 | } |
el13tjoc | 0:39399720eaeb | 471 | if(numberValues[minDistance] >= numberValues[maxDistance]) { |
el13tjoc | 0:39399720eaeb | 472 | if(menu[state].associatedValueIndex == minDistance) { |
el13tjoc | 0:39399720eaeb | 473 | ///If the min distance is greater than the max distance make it 1 less than the maximum |
el13tjoc | 0:39399720eaeb | 474 | numberValues[minDistance] = numberValues[maxDistance] - 1; |
el13tjoc | 0:39399720eaeb | 475 | } else { |
el13tjoc | 0:39399720eaeb | 476 | ///If the max distance is less than the max distance make it 1 more than the minimum |
el13tjoc | 0:39399720eaeb | 477 | numberValues[maxDistance] = numberValues[minDistance] + 1; |
el13tjoc | 0:39399720eaeb | 478 | } |
el13tjoc | 0:39399720eaeb | 479 | } |
el13tjoc | 0:39399720eaeb | 480 | } |
el13tjoc | 0:39399720eaeb | 481 | |
el13tjoc | 0:39399720eaeb | 482 | void immediateUpdates() { |
el13tjoc | 0:39399720eaeb | 483 | if(menu[state].associatedValueIndex == maxDistance) { |
el13tjoc | 0:39399720eaeb | 484 | ///If the associated value is the max distance, set the range of the SRF08 |
el13tjoc | 0:39399720eaeb | 485 | SRF08.setRangeRegister((int)((numberValues[maxDistance]-43.0)/43.0)); |
el13tjoc | 0:39399720eaeb | 486 | } |
el13tjoc | 0:39399720eaeb | 487 | if(menu[state].associatedValueIndex == distanceSmoothing) { |
el13tjoc | 0:39399720eaeb | 488 | ///If the associated value is the distanceSmoothing value, resize the smoothingValues vector |
el13tjoc | 0:39399720eaeb | 489 | smoothingValues.resize(numberValues[distanceSmoothing]+1); |
el13tjoc | 0:39399720eaeb | 490 | } |
el13tjoc | 0:39399720eaeb | 491 | } |