Components and supplies
Arduino Nano R3
Tools and machines
3D Printer (generic)
Project description
Code
MTC code
c_cpp
My code for the MTC
1/* Master Turret Control - Actual 2 * Chris Nowak - MAR 2019 3 * This is the handheld MTC module. 4 * https://www.instructables.com/member/ChrisN219/ 5 * https://create.arduino.cc/projecthub/Novachris/talking-portal-2-turret-gun-637bf3 6 * 7 * This code includes all the features needed to control up to three turrets, 8 * perform the Cara Mia Opera, Chat Time and Manual mode. 9 * The turrets are featured on another build. The turret 10 * will operate autonomously using this code without the MTC. 11 * 12 * The code is built to work with three turrets, but each will operate independently. 13 * Lots of debugging code left in. Use or clean up as desired. It's mostly debugged, 14 * but isn't perfect. Given the price you paid, I figure that's ok! ;) 15*/ 16 17#include <RF24.h> 18#include <RF24Network.h> 19#include <SPI.h> 20#include <Adafruit_GFX.h> 21#include <Adafruit_SSD1306.h> 22 23Adafruit_SSD1306 display(4); 24#define LOGO32_GLCD_HEIGHT 32 25#define LOGO32_GLCD_WIDTH 32 26static const unsigned char PROGMEM logo32_glcd_bmp[] = 27{ B00000000, B00000001, B10000000, B00000000, 28 B00000000, B00000110, B01100000, B00000000, 29 B00000000, B00011000, B00011000, B00000000, 30 B00000000, B00010000, B00001000, B00000000, 31 B00000000, B00110000, B00001100, B00000000, 32 B00001100, B00001000, B00010000, B00011000, 33 B00110000, B00011000, B00011000, B00001100, 34 B01110000, B00010001, B10001000, B00001110, 35 B01100000, B00110011, B11001100, B00000110, 36 B01100000, B00100011, B11000100, B00000110, 37 B11000000, B00110001, B10001100, B00000011, 38 B11000000, B00100000, B00000100, B00000011, 39 B11000000, B00110000, B00001100, B00000011, 40 B11000000, B00010000, B00001000, B00000011, 41 B01100000, B00010000, B00001000, B00000110, 42 B00110000, B00001100, B00110000, B00001100, 43 44 B00011000, B00000011, B11000000, B00011000, 45 B00000110, B00001101, B10110000, B01100000, 46 B00000000, B00110001, B10001100, B00000000, 47 B00000000, B11000001, B10000011, B00000000, 48 B00000001, B10000001, B10000001, B10000000, 49 B00000110, B00000001, B10000000, B01100000, 50 B00011000, B00000001, B10000000, B00011000, 51 B00110000, B00000001, B10000000, B00001100, 52 B01100000, B00000001, B10000000, B00000110, 53 B01100000, B00000001, B10000000, B00000110, 54 B11000000, B00000001, B10000000, B00000011, 55 B11000000, B00000001, B10000000, B00000011, 56 B11000000, B00000001, B10000000, B00000011, 57 B11000000, B00000001, B10000000, B00000011, 58 B11000000, B00000001, B10000000, B00000011, 59 B11000000, B00000000, B00000100, B00000011 }; 60 61RF24 radio(10, 9); // nRF24L01 (CE,CSN) 62RF24Network network(radio); 63const uint64_t this_node = 00; // 64const uint64_t RED = 01; // turret #1 - Red Turret 65const uint64_t WHT = 02; // turret #2 - White Turret 66const uint64_t BLU = 03; // turret #3 - Blue Turret 67 68byte pb1 = A2; // Select (GRN) "X" 69byte pb2 = A1; // Select 2 (WHT) "T" 70byte pb3 = A0; // Break (Red) "<" 71byte joyX=A6; 72byte joyY=A7; 73byte joyButton = A3; // joystick press 74 75byte ledManual = 5; // LED for signalling Manual Mode (BLUE) 76byte ledNotReady = 6; // LED for signalling that turrets busy (RED) 77byte ledOkToGo = 7; // LED signalling ready for action (GREEN) 78 79byte power = 8; // Through a pinout to show Nano powered and working 80int goState; // Aria =1, Chatty = 2, Manual = 3 81int pb1State; 82int pb2State; 83int pb3State; 84byte joyButtonState; 85byte busyWhite = 0; 86byte busyRed = 0; 87byte busyBlue = 0; 88byte notReady; 89byte DataRead; 90int x=0; 91int y=0; 92int z=0; 93byte MainBusy = 1; 94byte MainAria = 0; 95byte MainChat = 0; 96byte MainManual = 0; 97byte MenuSelection = 0; 98int Rx = 0; 99int Wx = 0; 100int Bx = 0; 101byte RedHere = 0; 102byte WhiteHere = 0; 103byte BlueHere = 0; 104byte selectTurret; 105 106/////////////////////////////////////////////////////////////////// 107//============================ SETUP ============================// 108/////////////////////////////////////////////////////////////////// 109void setup() { 110 Serial.begin(9600);// 111 SPI.begin(); 112 radio.begin(); 113 radio.setPALevel(RF24_PA_LOW); 114 radio.setDataRate(RF24_2MBPS); 115 radio.enableAckPayload(); 116 network.begin(70, this_node); //(channel, node address) 117 pinMode(pb1, INPUT_PULLUP); 118 pinMode(pb2, INPUT_PULLUP); 119 pinMode(pb3, INPUT_PULLUP); 120 pinMode(joyButton, INPUT_PULLUP); 121 pinMode(ledManual, OUTPUT); 122 pinMode(ledNotReady, OUTPUT); 123 pinMode(ledOkToGo, OUTPUT); 124 pinMode(power, OUTPUT); 125 radio.printDetails(); 126 digitalWrite (power, HIGH); 127 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 128 display.clearDisplay(); 129 display.display(); 130 display.setRotation(2); // yellow band on bottom. 0 is for yellow on top 131 Splash(); 132 delay (5000); // Display spash screen for 5 seconds. 133 display.clearDisplay(); 134 MenuSelection = 1; 135 for (int i=0; i <= 20; i++){ // quick net check to see which turrets around 136 ReadNet(); 137 TurretCheck(); 138 } 139} 140/////////////////////////////////////////////////////////////////// 141//========================= MAIN LOOP ===========================// 142/////////////////////////////////////////////////////////////////// 143void loop() { 144 //===== No turrets connected =====// 145 while ((RedHere == 0) && (WhiteHere == 0) && (BlueHere == 0)){ 146 ReadNet(); 147 display.setTextColor(WHITE); 148 display.setTextSize(0); 149 display.setCursor(20,0); display.print("No Turrets!"); 150 display.setCursor(0,8); display.print("Check to make sure "); 151 display.setCursor(0,16); display.print("Turrets powered up"); 152 display.setCursor(0,24); display.print("and ready to go..."); 153 display.display(); 154 display.clearDisplay (); 155 } 156 157 //===== Turret Busy somewhere =====// 158 while ((busyWhite == 1) || (busyRed == 1) || (busyBlue == 1)) { 159 BusyScreen(); 160 ReadNet(); 161 digitalWrite (ledOkToGo, LOW); 162 digitalWrite (ledNotReady, HIGH); 163 } 164 //===== Read inputs =====// 165 x=analogRead(joyX); 166 y=analogRead(joyY); 167 pb1State = digitalRead(pb1); // "X" 168 pb2State = digitalRead(pb2); // "T" 169 pb3State = digitalRead(pb3); // "<" 170 joyButtonState = digitalRead(joyButton); // "." 171 172 //===== Main Menu loop - Wait for input or Turret to get busy =====// 173 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 174 digitalWrite (ledOkToGo, HIGH); 175 digitalWrite (ledNotReady, LOW); 176 ReadNet(); 177 WriteNet(); 178 goState = 0; 179 MainBusy = 0; 180 } 181 //===== Use Joystick for menu selection =====// 182 if (MainBusy == 0) { 183 if (y < 300) {--MenuSelection;} 184 if (y > 700) {MenuSelection++;} 185 if (MenuSelection > 3) {MenuSelection = 1;} 186 if (MenuSelection < 1) {MenuSelection = 3;} 187 MainMenu(); 188 } 189 //===== Check turret status =====// 190 if (pb2State == 0) { 191 do { 192 TurretCheck(); 193 pb3State = digitalRead(pb3); 194 WriteNet(); 195 ReadNet(); 196 Serial.println(); 197 } 198 while (pb3State != 0); // press '<' button to exit status screen 199 } 200 //===== Go to ARIA Mode =====// 201 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 1)){ 202 MainBusy = 1; 203 goState = 1; 204 digitalWrite (ledOkToGo, LOW); 205 digitalWrite (ledNotReady, HIGH); 206 AriaMode(); 207 } 208 //===== Go to CHAT Mode =====// 209 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 2)) { 210 MainBusy = 1; 211 goState = 2; 212 digitalWrite (ledOkToGo, LOW); 213 digitalWrite (ledNotReady, LOW); 214 chatMode(); 215 } 216 //===== Go to MANUAL CONTROL Mode =====// 217 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 3)) { 218 MainBusy = 1; 219 goState = 3; 220 digitalWrite (ledOkToGo, LOW); 221 digitalWrite (ledNotReady, LOW); 222 digitalWrite (ledManual, HIGH); 223 manualControl(); 224 } 225 else { 226 digitalWrite(ledManual, LOW); 227 } 228 //====== Debugging Monitor ========// 229 Serial.println(); 230 Serial.print(F("-MTC- ")); 231 Serial.print(F("goState: "));Serial.print (goState); Serial.print (" "); 232/* Serial.print(F("White :"));Serial.print (busyWhite); Serial.print (" "); 233 Serial.print(F("Red :"));Serial.print (busyRed); Serial.print (" "); 234 Serial.print(F("Blue :"));Serial.print (busyBlue); Serial.print (" "); 235 Serial.print(F("RedHr :"));Serial.print (RedHere); Serial.print (" "); 236 Serial.print(F("WhtHr :"));Serial.print (WhiteHere); Serial.print (" "); 237 Serial.print(F("BluHr :"));Serial.print (BlueHere); Serial.print (" "); 238 Serial.print(F("x :"));Serial.print (x); Serial.print ("\ "); 239 Serial.print(F("y :"));Serial.print (y); Serial.print ("\ "); 240*/ 241 Serial.print(F("pb1 :"));Serial.print (pb1State); Serial.print (" "); 242 Serial.print(F("pb2 :"));Serial.print (pb2State); Serial.print (" "); 243 Serial.print(F("pb3 :"));Serial.print (pb3State); Serial.print (" "); 244 Serial.print(F("jy4 :"));Serial.print (joyButtonState); Serial.print (" "); 245} 246/////////////////////////////////////////////////////////////////// 247//======================= DISPLAY SCREENS =======================// 248/////////////////////////////////////////////////////////////////// 249 250//------------- Opening Splash Screen ---------------// 251void Splash (){ 252 display.clearDisplay(); 253 display.setTextColor(WHITE); 254 display.drawBitmap(0, 0, logo32_glcd_bmp, 32, 32, 1); 255 display.drawBitmap(46, 0, logo32_glcd_bmp, 32, 32, 1); 256 display.drawBitmap(92, 0, logo32_glcd_bmp, 32, 32, 1); 257 display.fillRect(0,24,124,8, BLACK); 258 display.setCursor(4,24); display.print("== Turret Control =="); 259 display.display(); 260} 261//------------- Main Menu ---------------// 262void MainMenu () { // display menu 263 display.setTextSize(0); // display text on screen 264 display.setTextColor(WHITE); 265 if (MenuSelection == 1) { 266 display.setTextSize(0); 267 display.setCursor(0,24); display.print("----- SELECTION -----"); 268 display.setCursor(24,0); display.print(" == ARIA =="); 269 display.setCursor(24,8); display.print(" Chat"); 270 display.setCursor(24,16); display.print(" Manual");} 271 if (MenuSelection == 2) { 272 display.setCursor(0,24); display.print("----- SELECTION -----"); 273 display.setCursor(24,0); display.print(" Aria"); 274 display.setCursor(24,8); display.print(" == CHAT =="); 275 display.setCursor(24,16); display.print(" Manual");} 276 if (MenuSelection == 3) { 277 display.setCursor(0,24); display.print("----- SELECTION -----"); 278 display.setCursor(24,0); display.print(" Aria"); 279 display.setCursor(24,8); display.print(" Chat"); 280 display.setCursor(24,16); display.print("== MANUAL ==");} 281 display.display(); 282 display.clearDisplay (); 283} 284//------------- Busy Screen ---------------// 285void BusyScreen () { // display menu 286 display.setTextSize(0); // display text on screen 287 display.setTextColor(WHITE); 288 display.setTextSize(0); 289 display.setCursor(20,24); display.print("BUSY RIGHT NOW"); 290 display.setCursor(0,0); display.print("Sorry, I'm busy "); 291 display.setCursor(0,8); display.print("right now, dealing"); 292 display.setCursor(0,16); display.print("with you people..."); 293 display.display(); 294 display.clearDisplay (); 295} 296 297//-------- Turret Check Screen ---------------// 298void TurretCheck() { 299 display.setTextColor(WHITE); 300 display.setTextSize(0); 301 display.setCursor(26,24); display.print("Turret Status"); 302 303 display.setCursor(0,0); display.print("Red: "); 304 if (busyRed == 1) {display.setCursor(38,0); display.print ("Busy");} 305 else if (RedHere == 1) {display.setCursor(38,0); display.print ("Ready");} 306 else {display.setCursor(38,0); display.print ("not available");} 307 308 display.setCursor(0,8); display.print("White: "); 309 if (busyWhite == 1) {display.setCursor(38,8); display.print ("Busy");} 310 else if (WhiteHere == 1) {display.setCursor(38,8); display.print ("Ready");} 311 else {display.setCursor(38,8); display.print ("not available");} 312 313 display.setCursor(0,16); display.print("Blue: "); 314 if (busyBlue == 1) {display.setCursor(38,16); display.print ("Busy");} 315 else if (BlueHere == 1) {display.setCursor(38,16); display.print ("Ready");} 316 else {display.setCursor(38,16); display.print ("not available");} 317 318 display.display(); 319 display.clearDisplay (); 320} 321/////////////////////////////////////////////////////////////////// 322//======================= ARIA MODE =============================// 323/////////////////////////////////////////////////////////////////// 324void AriaMode () { 325 for (int i=0; i <= 10; i++){ // Make sure the turrets get the message. 326 WriteNet(); 327 } 328 MenuSelection = 1; 329 int i=0; 330 goState = 0; 331 do { 332 i++; 333 display.setTextSize(2); // display text on screen 334 display.setTextColor(WHITE); 335 display.setCursor(8,8); display.print("ARIA MODE"); 336 display.fillRect(0,24,120,4, WHITE); // 337 display.fillRect(0+(i),2,40,4, WHITE);; 338 display.display(); 339 display.clearDisplay (); 340 pb3State = digitalRead(pb3); 341 ReadNet(); 342 WriteNet(); 343 if (i > 80) (i = 0); 344 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 345 return; 346 } 347 } 348 while (pb3State != 0); 349 for (int i=0; i <= 10; i++){ 350 WriteNet(); 351 } 352} 353/////////////////////////////////////////////////////////////////// 354//======================= CHAT MODE =============================// 355/////////////////////////////////////////////////////////////////// 356void chatMode() { 357 for (int i=0; i <= 10; i++){ // Make sure the turrets get the message. 358 WriteNet(); 359 } 360 Serial.println(); 361 digitalWrite (ledOkToGo, LOW); 362 digitalWrite (ledNotReady, HIGH); 363 MenuSelection = 2; 364 int i=0; 365 goState = 0; 366 do { 367 WriteNet(); 368 ReadNet(); 369 Serial.println(); 370 i++; 371 display.setTextSize(2); // display text on screen 372 display.setTextColor(WHITE); 373 display.setCursor(8,8); display.print("CHAT MODE"); 374 display.fillRect(0,24,120,4, WHITE); // 375 display.fillRect(0+i,2,40,4, WHITE); 376 display.display(); 377 display.clearDisplay (); 378 pb3State = digitalRead(pb3); 379 if (i > 80) (i = 0); 380 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 381 return; 382 } 383 } 384 while (pb3State != 0); 385 for (int i=0; i <= 10; i++){ 386 WriteNet(); 387 } 388} 389/////////////////////////////////////////////////////////////////// 390//======================= MANUAL CONTROL ========================// 391/////////////////////////////////////////////////////////////////// 392void manualControl() { 393 WriteNet(); 394 Serial.println(); 395 selectTurret = 2; 396 MenuSelection = 3; 397 display.setTextSize(2); // display text on screen 398 display.setTextColor(WHITE); 399 display.setCursor(0,8); display.print("MANUAL CTL"); 400 display.fillRect(0,24,128,4, WHITE); // 401 display.fillRect(0,2,128,4, WHITE);; 402 display.display(); 403 do { 404 x=analogRead(joyX); 405 y=analogRead(joyY); 406 pb1State = digitalRead(pb1); // Fire (GRN) 407 pb2State = digitalRead(pb2); // Say random comment (WHT) 408 pb3State = digitalRead(pb3); // Break (RED) 409 WriteNet(); 410 Serial.println(); 411 } 412 while (pb3State != 0); 413 goState = 0; 414 display.clearDisplay (); 415 ReadNet(); 416 for (int i=0; i <= 10; i++){ 417 WriteNet(); 418 } 419 Serial.println(); 420} 421 422/////////////////////////////////////////////////////////////////// 423//========================= RECEIVING ===========================// 424/////////////////////////////////////////////////////////////////// 425void ReadNet(){ 426 network.update(); 427 for (int i=0; i <= 10; i++){ 428 if ( network.available() ) { 429 RF24NetworkHeader header; 430 network.peek(header); 431 network.read(header, &DataRead, sizeof(DataRead)); 432 if (header.from_node == 01){ // get data from RED 433 busyRed = DataRead; 434 RedHere = 1;} // RED is recognized 435 if (header.from_node == 02){ 436 busyWhite = DataRead; 437 WhiteHere = 1;} 438 if (header.from_node == 03){ 439 busyBlue = DataRead; 440 BlueHere = 1;} 441 } 442 } 443} 444/////////////////////////////////////////////////////////////////// 445//========================= SENDING ===========================// 446/////////////////////////////////////////////////////////////////// 447void WriteNet(){ 448 network.update(); 449 int payload [] = {x, y, pb1State, pb2State, pb3State, goState}; 450 451 RF24NetworkHeader header14(RED); 452 bool ok14 = network.write(header14, &payload, sizeof(payload)); 453 if (ok14) { 454 Rx = 0; 455 Serial.print("RED ok14 ");} 456 else { 457 Rx++; 458 Serial.print("-------- ");} 459 460 RF24NetworkHeader header16(WHT); 461 bool ok16 = network.write(header16, &payload, sizeof(payload)); 462 if (ok16) { 463 Wx = 0; 464 Serial.print("WHT ok16 ");} 465 else { 466 Wx++; 467 Serial.print("-------- ");} 468 469 RF24NetworkHeader header18(BLU); 470 bool ok18 = network.write(header18, &payload, sizeof(payload)); 471 if (ok18) { 472 Bx = 0; 473 Serial.print("BLU ok18 ");} 474 else { 475 Bx++; 476 Serial.print("-------- ");} 477 478 if (Rx >= 10){RedHere = 0;} // to check if communication lost and record it. 479 else {RedHere = 1;} 480 if (Wx >= 10){WhiteHere = 0;} 481 else WhiteHere = 1; 482 if (Bx >= 10){BlueHere = 0;} 483 else {BlueHere = 1;} 484 485 Serial.print(F("Rx :"));Serial.print (Rx); Serial.print (" "); 486 Serial.print(F("RedHere :"));Serial.print (RedHere); Serial.print (" "); 487 Serial.print(F("Wx :"));Serial.print (Wx); Serial.print (" "); 488 Serial.print(F("WhiteHere :"));Serial.print (WhiteHere); Serial.print (" "); 489 Serial.print(F("Bx :"));Serial.print (Bx); Serial.print (" "); 490 Serial.print(F("BlueHere :"));Serial.print (BlueHere); Serial.print (" "); 491} 492
MTC code
c_cpp
My code for the MTC
1/* Master Turret Control - Actual 2 * Chris Nowak - MAR 2019 3 * This is the handheld MTC module. 4 * https://www.instructables.com/member/ChrisN219/ 5 * https://create.arduino.cc/projecthub/Novachris/talking-portal-2-turret-gun-637bf3 6 * 7 * This code includes all the features needed to control up to three turrets, 8 * perform the Cara Mia Opera, Chat Time and Manual mode. 9 * The turrets are featured on another build. The turret 10 * will operate autonomously using this code without the MTC. 11 * 12 * The code is built to work with three turrets, but each will operate independently. 13 * Lots of debugging code left in. Use or clean up as desired. It's mostly debugged, 14 * but isn't perfect. Given the price you paid, I figure that's ok! ;) 15*/ 16 17#include <RF24.h> 18#include <RF24Network.h> 19#include <SPI.h> 20#include <Adafruit_GFX.h> 21#include <Adafruit_SSD1306.h> 22 23Adafruit_SSD1306 display(4); 24#define LOGO32_GLCD_HEIGHT 32 25#define LOGO32_GLCD_WIDTH 32 26static const unsigned char PROGMEM logo32_glcd_bmp[] = 27{ B00000000, B00000001, B10000000, B00000000, 28 B00000000, B00000110, B01100000, B00000000, 29 B00000000, B00011000, B00011000, B00000000, 30 B00000000, B00010000, B00001000, B00000000, 31 B00000000, B00110000, B00001100, B00000000, 32 B00001100, B00001000, B00010000, B00011000, 33 B00110000, B00011000, B00011000, B00001100, 34 B01110000, B00010001, B10001000, B00001110, 35 B01100000, B00110011, B11001100, B00000110, 36 B01100000, B00100011, B11000100, B00000110, 37 B11000000, B00110001, B10001100, B00000011, 38 B11000000, B00100000, B00000100, B00000011, 39 B11000000, B00110000, B00001100, B00000011, 40 B11000000, B00010000, B00001000, B00000011, 41 B01100000, B00010000, B00001000, B00000110, 42 B00110000, B00001100, B00110000, B00001100, 43 44 B00011000, B00000011, B11000000, B00011000, 45 B00000110, B00001101, B10110000, B01100000, 46 B00000000, B00110001, B10001100, B00000000, 47 B00000000, B11000001, B10000011, B00000000, 48 B00000001, B10000001, B10000001, B10000000, 49 B00000110, B00000001, B10000000, B01100000, 50 B00011000, B00000001, B10000000, B00011000, 51 B00110000, B00000001, B10000000, B00001100, 52 B01100000, B00000001, B10000000, B00000110, 53 B01100000, B00000001, B10000000, B00000110, 54 B11000000, B00000001, B10000000, B00000011, 55 B11000000, B00000001, B10000000, B00000011, 56 B11000000, B00000001, B10000000, B00000011, 57 B11000000, B00000001, B10000000, B00000011, 58 B11000000, B00000001, B10000000, B00000011, 59 B11000000, B00000000, B00000100, B00000011 }; 60 61RF24 radio(10, 9); // nRF24L01 (CE,CSN) 62RF24Network network(radio); 63const uint64_t this_node = 00; // 64const uint64_t RED = 01; // turret #1 - Red Turret 65const uint64_t WHT = 02; // turret #2 - White Turret 66const uint64_t BLU = 03; // turret #3 - Blue Turret 67 68byte pb1 = A2; // Select (GRN) "X" 69byte pb2 = A1; // Select 2 (WHT) "T" 70byte pb3 = A0; // Break (Red) "<" 71byte joyX=A6; 72byte joyY=A7; 73byte joyButton = A3; // joystick press 74 75byte ledManual = 5; // LED for signalling Manual Mode (BLUE) 76byte ledNotReady = 6; // LED for signalling that turrets busy (RED) 77byte ledOkToGo = 7; // LED signalling ready for action (GREEN) 78 79byte power = 8; // Through a pinout to show Nano powered and working 80int goState; // Aria =1, Chatty = 2, Manual = 3 81int pb1State; 82int pb2State; 83int pb3State; 84byte joyButtonState; 85byte busyWhite = 0; 86byte busyRed = 0; 87byte busyBlue = 0; 88byte notReady; 89byte DataRead; 90int x=0; 91int y=0; 92int z=0; 93byte MainBusy = 1; 94byte MainAria = 0; 95byte MainChat = 0; 96byte MainManual = 0; 97byte MenuSelection = 0; 98int Rx = 0; 99int Wx = 0; 100int Bx = 0; 101byte RedHere = 0; 102byte WhiteHere = 0; 103byte BlueHere = 0; 104byte selectTurret; 105 106/////////////////////////////////////////////////////////////////// 107//============================ SETUP ============================// 108/////////////////////////////////////////////////////////////////// 109void setup() { 110 Serial.begin(9600);// 111 SPI.begin(); 112 radio.begin(); 113 radio.setPALevel(RF24_PA_LOW); 114 radio.setDataRate(RF24_2MBPS); 115 radio.enableAckPayload(); 116 network.begin(70, this_node); //(channel, node address) 117 pinMode(pb1, INPUT_PULLUP); 118 pinMode(pb2, INPUT_PULLUP); 119 pinMode(pb3, INPUT_PULLUP); 120 pinMode(joyButton, INPUT_PULLUP); 121 pinMode(ledManual, OUTPUT); 122 pinMode(ledNotReady, OUTPUT); 123 pinMode(ledOkToGo, OUTPUT); 124 pinMode(power, OUTPUT); 125 radio.printDetails(); 126 digitalWrite (power, HIGH); 127 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 128 display.clearDisplay(); 129 display.display(); 130 display.setRotation(2); // yellow band on bottom. 0 is for yellow on top 131 Splash(); 132 delay (5000); // Display spash screen for 5 seconds. 133 display.clearDisplay(); 134 MenuSelection = 1; 135 for (int i=0; i <= 20; i++){ // quick net check to see which turrets around 136 ReadNet(); 137 TurretCheck(); 138 } 139} 140/////////////////////////////////////////////////////////////////// 141//========================= MAIN LOOP ===========================// 142/////////////////////////////////////////////////////////////////// 143void loop() { 144 //===== No turrets connected =====// 145 while ((RedHere == 0) && (WhiteHere == 0) && (BlueHere == 0)){ 146 ReadNet(); 147 display.setTextColor(WHITE); 148 display.setTextSize(0); 149 display.setCursor(20,0); display.print("No Turrets!"); 150 display.setCursor(0,8); display.print("Check to make sure "); 151 display.setCursor(0,16); display.print("Turrets powered up"); 152 display.setCursor(0,24); display.print("and ready to go..."); 153 display.display(); 154 display.clearDisplay (); 155 } 156 157 //===== Turret Busy somewhere =====// 158 while ((busyWhite == 1) || (busyRed == 1) || (busyBlue == 1)) { 159 BusyScreen(); 160 ReadNet(); 161 digitalWrite (ledOkToGo, LOW); 162 digitalWrite (ledNotReady, HIGH); 163 } 164 //===== Read inputs =====// 165 x=analogRead(joyX); 166 y=analogRead(joyY); 167 pb1State = digitalRead(pb1); // "X" 168 pb2State = digitalRead(pb2); // "T" 169 pb3State = digitalRead(pb3); // "<" 170 joyButtonState = digitalRead(joyButton); // "." 171 172 //===== Main Menu loop - Wait for input or Turret to get busy =====// 173 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 174 digitalWrite (ledOkToGo, HIGH); 175 digitalWrite (ledNotReady, LOW); 176 ReadNet(); 177 WriteNet(); 178 goState = 0; 179 MainBusy = 0; 180 } 181 //===== Use Joystick for menu selection =====// 182 if (MainBusy == 0) { 183 if (y < 300) {--MenuSelection;} 184 if (y > 700) {MenuSelection++;} 185 if (MenuSelection > 3) {MenuSelection = 1;} 186 if (MenuSelection < 1) {MenuSelection = 3;} 187 MainMenu(); 188 } 189 //===== Check turret status =====// 190 if (pb2State == 0) { 191 do { 192 TurretCheck(); 193 pb3State = digitalRead(pb3); 194 WriteNet(); 195 ReadNet(); 196 Serial.println(); 197 } 198 while (pb3State != 0); // press '<' button to exit status screen 199 } 200 //===== Go to ARIA Mode =====// 201 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 1)){ 202 MainBusy = 1; 203 goState = 1; 204 digitalWrite (ledOkToGo, LOW); 205 digitalWrite (ledNotReady, HIGH); 206 AriaMode(); 207 } 208 //===== Go to CHAT Mode =====// 209 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 2)) { 210 MainBusy = 1; 211 goState = 2; 212 digitalWrite (ledOkToGo, LOW); 213 digitalWrite (ledNotReady, LOW); 214 chatMode(); 215 } 216 //===== Go to MANUAL CONTROL Mode =====// 217 if (((pb1State == 0)||(joyButtonState == 0)) && (MenuSelection == 3)) { 218 MainBusy = 1; 219 goState = 3; 220 digitalWrite (ledOkToGo, LOW); 221 digitalWrite (ledNotReady, LOW); 222 digitalWrite (ledManual, HIGH); 223 manualControl(); 224 } 225 else { 226 digitalWrite(ledManual, LOW); 227 } 228 //====== Debugging Monitor ========// 229 Serial.println(); 230 Serial.print(F("-MTC- ")); 231 Serial.print(F("goState: "));Serial.print (goState); Serial.print (" "); 232/* Serial.print(F("White :"));Serial.print (busyWhite); Serial.print (" "); 233 Serial.print(F("Red :"));Serial.print (busyRed); Serial.print (" "); 234 Serial.print(F("Blue :"));Serial.print (busyBlue); Serial.print (" "); 235 Serial.print(F("RedHr :"));Serial.print (RedHere); Serial.print (" "); 236 Serial.print(F("WhtHr :"));Serial.print (WhiteHere); Serial.print (" "); 237 Serial.print(F("BluHr :"));Serial.print (BlueHere); Serial.print (" "); 238 Serial.print(F("x :"));Serial.print (x); Serial.print ("\ "); 239 Serial.print(F("y :"));Serial.print (y); Serial.print ("\ "); 240*/ 241 Serial.print(F("pb1 :"));Serial.print (pb1State); Serial.print (" "); 242 Serial.print(F("pb2 :"));Serial.print (pb2State); Serial.print (" "); 243 Serial.print(F("pb3 :"));Serial.print (pb3State); Serial.print (" "); 244 Serial.print(F("jy4 :"));Serial.print (joyButtonState); Serial.print (" "); 245} 246/////////////////////////////////////////////////////////////////// 247//======================= DISPLAY SCREENS =======================// 248/////////////////////////////////////////////////////////////////// 249 250//------------- Opening Splash Screen ---------------// 251void Splash (){ 252 display.clearDisplay(); 253 display.setTextColor(WHITE); 254 display.drawBitmap(0, 0, logo32_glcd_bmp, 32, 32, 1); 255 display.drawBitmap(46, 0, logo32_glcd_bmp, 32, 32, 1); 256 display.drawBitmap(92, 0, logo32_glcd_bmp, 32, 32, 1); 257 display.fillRect(0,24,124,8, BLACK); 258 display.setCursor(4,24); display.print("== Turret Control =="); 259 display.display(); 260} 261//------------- Main Menu ---------------// 262void MainMenu () { // display menu 263 display.setTextSize(0); // display text on screen 264 display.setTextColor(WHITE); 265 if (MenuSelection == 1) { 266 display.setTextSize(0); 267 display.setCursor(0,24); display.print("----- SELECTION -----"); 268 display.setCursor(24,0); display.print(" == ARIA =="); 269 display.setCursor(24,8); display.print(" Chat"); 270 display.setCursor(24,16); display.print(" Manual");} 271 if (MenuSelection == 2) { 272 display.setCursor(0,24); display.print("----- SELECTION -----"); 273 display.setCursor(24,0); display.print(" Aria"); 274 display.setCursor(24,8); display.print(" == CHAT =="); 275 display.setCursor(24,16); display.print(" Manual");} 276 if (MenuSelection == 3) { 277 display.setCursor(0,24); display.print("----- SELECTION -----"); 278 display.setCursor(24,0); display.print(" Aria"); 279 display.setCursor(24,8); display.print(" Chat"); 280 display.setCursor(24,16); display.print("== MANUAL ==");} 281 display.display(); 282 display.clearDisplay (); 283} 284//------------- Busy Screen ---------------// 285void BusyScreen () { // display menu 286 display.setTextSize(0); // display text on screen 287 display.setTextColor(WHITE); 288 display.setTextSize(0); 289 display.setCursor(20,24); display.print("BUSY RIGHT NOW"); 290 display.setCursor(0,0); display.print("Sorry, I'm busy "); 291 display.setCursor(0,8); display.print("right now, dealing"); 292 display.setCursor(0,16); display.print("with you people..."); 293 display.display(); 294 display.clearDisplay (); 295} 296 297//-------- Turret Check Screen ---------------// 298void TurretCheck() { 299 display.setTextColor(WHITE); 300 display.setTextSize(0); 301 display.setCursor(26,24); display.print("Turret Status"); 302 303 display.setCursor(0,0); display.print("Red: "); 304 if (busyRed == 1) {display.setCursor(38,0); display.print ("Busy");} 305 else if (RedHere == 1) {display.setCursor(38,0); display.print ("Ready");} 306 else {display.setCursor(38,0); display.print ("not available");} 307 308 display.setCursor(0,8); display.print("White: "); 309 if (busyWhite == 1) {display.setCursor(38,8); display.print ("Busy");} 310 else if (WhiteHere == 1) {display.setCursor(38,8); display.print ("Ready");} 311 else {display.setCursor(38,8); display.print ("not available");} 312 313 display.setCursor(0,16); display.print("Blue: "); 314 if (busyBlue == 1) {display.setCursor(38,16); display.print ("Busy");} 315 else if (BlueHere == 1) {display.setCursor(38,16); display.print ("Ready");} 316 else {display.setCursor(38,16); display.print ("not available");} 317 318 display.display(); 319 display.clearDisplay (); 320} 321/////////////////////////////////////////////////////////////////// 322//======================= ARIA MODE =============================// 323/////////////////////////////////////////////////////////////////// 324void AriaMode () { 325 for (int i=0; i <= 10; i++){ // Make sure the turrets get the message. 326 WriteNet(); 327 } 328 MenuSelection = 1; 329 int i=0; 330 goState = 0; 331 do { 332 i++; 333 display.setTextSize(2); // display text on screen 334 display.setTextColor(WHITE); 335 display.setCursor(8,8); display.print("ARIA MODE"); 336 display.fillRect(0,24,120,4, WHITE); // 337 display.fillRect(0+(i),2,40,4, WHITE);; 338 display.display(); 339 display.clearDisplay (); 340 pb3State = digitalRead(pb3); 341 ReadNet(); 342 WriteNet(); 343 if (i > 80) (i = 0); 344 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 345 return; 346 } 347 } 348 while (pb3State != 0); 349 for (int i=0; i <= 10; i++){ 350 WriteNet(); 351 } 352} 353/////////////////////////////////////////////////////////////////// 354//======================= CHAT MODE =============================// 355/////////////////////////////////////////////////////////////////// 356void chatMode() { 357 for (int i=0; i <= 10; i++){ // Make sure the turrets get the message. 358 WriteNet(); 359 } 360 Serial.println(); 361 digitalWrite (ledOkToGo, LOW); 362 digitalWrite (ledNotReady, HIGH); 363 MenuSelection = 2; 364 int i=0; 365 goState = 0; 366 do { 367 WriteNet(); 368 ReadNet(); 369 Serial.println(); 370 i++; 371 display.setTextSize(2); // display text on screen 372 display.setTextColor(WHITE); 373 display.setCursor(8,8); display.print("CHAT MODE"); 374 display.fillRect(0,24,120,4, WHITE); // 375 display.fillRect(0+i,2,40,4, WHITE); 376 display.display(); 377 display.clearDisplay (); 378 pb3State = digitalRead(pb3); 379 if (i > 80) (i = 0); 380 if ((busyWhite == 0) && (busyRed == 0) && (busyBlue == 0)) { 381 return; 382 } 383 } 384 while (pb3State != 0); 385 for (int i=0; i <= 10; i++){ 386 WriteNet(); 387 } 388} 389/////////////////////////////////////////////////////////////////// 390//======================= MANUAL CONTROL ========================// 391/////////////////////////////////////////////////////////////////// 392void manualControl() { 393 WriteNet(); 394 Serial.println(); 395 selectTurret = 2; 396 MenuSelection = 3; 397 display.setTextSize(2); // display text on screen 398 display.setTextColor(WHITE); 399 display.setCursor(0,8); display.print("MANUAL CTL"); 400 display.fillRect(0,24,128,4, WHITE); // 401 display.fillRect(0,2,128,4, WHITE);; 402 display.display(); 403 do { 404 x=analogRead(joyX); 405 y=analogRead(joyY); 406 pb1State = digitalRead(pb1); // Fire (GRN) 407 pb2State = digitalRead(pb2); // Say random comment (WHT) 408 pb3State = digitalRead(pb3); // Break (RED) 409 WriteNet(); 410 Serial.println(); 411 } 412 while (pb3State != 0); 413 goState = 0; 414 display.clearDisplay (); 415 ReadNet(); 416 for (int i=0; i <= 10; i++){ 417 WriteNet(); 418 } 419 Serial.println(); 420} 421 422/////////////////////////////////////////////////////////////////// 423//========================= RECEIVING ===========================// 424/////////////////////////////////////////////////////////////////// 425void ReadNet(){ 426 network.update(); 427 for (int i=0; i <= 10; i++){ 428 if ( network.available() ) { 429 RF24NetworkHeader header; 430 network.peek(header); 431 network.read(header, &DataRead, sizeof(DataRead)); 432 if (header.from_node == 01){ // get data from RED 433 busyRed = DataRead; 434 RedHere = 1;} // RED is recognized 435 if (header.from_node == 02){ 436 busyWhite = DataRead; 437 WhiteHere = 1;} 438 if (header.from_node == 03){ 439 busyBlue = DataRead; 440 BlueHere = 1;} 441 } 442 } 443} 444/////////////////////////////////////////////////////////////////// 445//========================= SENDING ===========================// 446/////////////////////////////////////////////////////////////////// 447void WriteNet(){ 448 network.update(); 449 int payload [] = {x, y, pb1State, pb2State, pb3State, goState}; 450 451 RF24NetworkHeader header14(RED); 452 bool ok14 = network.write(header14, &payload, sizeof(payload)); 453 if (ok14) { 454 Rx = 0; 455 Serial.print("RED ok14 ");} 456 else { 457 Rx++; 458 Serial.print("-------- ");} 459 460 RF24NetworkHeader header16(WHT); 461 bool ok16 = network.write(header16, &payload, sizeof(payload)); 462 if (ok16) { 463 Wx = 0; 464 Serial.print("WHT ok16 ");} 465 else { 466 Wx++; 467 Serial.print("-------- ");} 468 469 RF24NetworkHeader header18(BLU); 470 bool ok18 = network.write(header18, &payload, sizeof(payload)); 471 if (ok18) { 472 Bx = 0; 473 Serial.print("BLU ok18 ");} 474 else { 475 Bx++; 476 Serial.print("-------- ");} 477 478 if (Rx >= 10){RedHere = 0;} // to check if communication lost and record it. 479 else {RedHere = 1;} 480 if (Wx >= 10){WhiteHere = 0;} 481 else WhiteHere = 1; 482 if (Bx >= 10){BlueHere = 0;} 483 else {BlueHere = 1;} 484 485 Serial.print(F("Rx :"));Serial.print (Rx); Serial.print (" "); 486 Serial.print(F("RedHere :"));Serial.print (RedHere); Serial.print (" "); 487 Serial.print(F("Wx :"));Serial.print (Wx); Serial.print (" "); 488 Serial.print(F("WhiteHere :"));Serial.print (WhiteHere); Serial.print (" "); 489 Serial.print(F("Bx :"));Serial.print (Bx); Serial.print (" "); 490 Serial.print(F("BlueHere :"));Serial.print (BlueHere); Serial.print (" "); 491} 492
Downloadable files
Wiring Schematic - MTC
The wiring schematic I made to build the MTC
Wiring Schematic - MTC
Documentation
Controller+-+Top+Plate+Yellow+on+top.stl
Controller+-+Top+Plate+Yellow+on+top.stl
Controller+-+Screen+strap.stl
Controller+-+Screen+strap.stl
Controller parts
The top plate ( 2 versions), bottom housing and little strap for LCD screen.
Controller parts
Controller+-+Top+Plate+Yellow+on+bottom.stl
Controller+-+Top+Plate+Yellow+on+bottom.stl
Controller+-+Bottom+v1.stl
Controller+-+Bottom+v1.stl
Controller+-+Screen+strap.stl
Controller+-+Screen+strap.stl
Controller+-+Top+Plate+Yellow+on+bottom.stl
Controller+-+Top+Plate+Yellow+on+bottom.stl
Controller+-+Top+Plate+Yellow+on+top.stl
Controller+-+Top+Plate+Yellow+on+top.stl
Controller+-+Bottom+v1.stl
Controller+-+Bottom+v1.stl
Controller parts
The top plate ( 2 versions), bottom housing and little strap for LCD screen.
Controller parts
Comments
Only logged in users can leave comments
Novachris
0 Followers
•0 Projects
Table of contents
Intro
9
0