AI-9 Gas Turbine ECU Control System (Jet Engine)
Start a Helicopter Gas Turbine APU engine using an Arduino Uno, This is what they were made for !
Components and supplies
Arduino Nano Every
Geekcreit 2 Channel Relay Module With Optocoupler For PIC AVR DSP ARM
3.5" inch Touch Screen TFT LCD 480x320 ILI9488 SPI Display 3.3V 5V
Geekcreit® 5V 4 Channel Relay Module For PIC ARM DSP AVR MSP430
Arduino UNO
Optocoupler DIP-4 PC817C
Prototyping Prototype Shield Mini Breadboard 5V 1A
Grove - 1-Wire Thermocouple Amplifier (MAX31850K)
XL4015 5A DC-DC Step Down Adjustable Power Supply Module Buck Converter
Tools and machines
Workshop, Milling Mc, Router and general tooling
Apps and platforms
Arduino IDE 2.0 (beta)
Project description
Code
Main Control System
arduino
I have never done this before and if i were to have another go, im sure i would do better. That said it does work and to test it i built another diagnostics box that responds the same way the engine would (Stops the missus shouting at me making all that noise) Its basically a huge time dependant loop I have used direct hardware ports to trigger the relay as talking to the SPI bus takes time and the Thermocouple read is slow (i may have to re look at that)
1/* 2 AI-9 APU Gas Turbine Launch (Main Control Panel) 3===================================================================== 4 5 Created 22/08/2021 6 by Derek Beacroft UK 7 8// Run fuel & Ignition 9// False Start Fuel No Ignition 10// Cold Scroll No Fuel No Ignition 11 12Display on I2C Line 13 CommandNo,"buff",Val 14 1,"",0 // Start 15 2,"",0 // Stop 16 3,"",0 // Reset Display 17 4,"message",0 // Display new message 18 5, 19 6,xxx // Temperature 20 7,xxx // Speed 21 8, 22 9, 23 10,"",01 // Over Speed 24 11,"",01 // Normal Speed 25 12,"",01 // Oil Pressure 26 13,"",01 // Centrifuge 27 14,"",01 // Boost Pump 28 29*/ 30#include <Wire.h> 31#include <OneWire.h> 32#include <DallasTemperature.h> 33 34 35// Data wire is plugged into port 3 on Arduino 36#define ONE_WIRE_BUS 15 // 15=A1 37// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 38OneWire oneWire(ONE_WIRE_BUS); 39// Pass our oneWire reference to Dallas Temperature. 40DallasTemperature sensors(&oneWire); 41 42 43#define Debug (bool) false // 44int l_time = millis()/1000; 45 46bool start = false; 47bool R1_eMotor = false; 48bool R2_eMotor = false; 49bool R3_Ignition = false; 50bool R4_FuelStart = false; 51bool R5_FuelRun= false; 52bool R6_Boost = false; 53 54bool Sence_OpenCentrifuge =false; // eMotor Switch Nc (default open until connected to engine) 55bool Sence_SpeedOk = false; // Fuel Pressure ok 56bool Sence_OilOk = false; // Oil Pressure ok 57bool Sence_OverSpeed = false; // Fuel Pressure over 58 59bool ColdScroll = false; 60bool FalseStart = false; 61bool BtnHeld = false; 62 63 64int val =0; 65int Value =0; 66int Sence_Temp=240; 67int Btn =0; 68unsigned int ReadBtn; 69 70unsigned long c = 0; 71unsigned long Temperature = 25; 72 73long StartupDebounceTime= 0; // the last time the output pin was toggled 74long lastDebounceTime = 0; // the last time the output pin was toggled 75#define debounceDelay (uint8_t) 400 // the debounce time; increase if the output flickers 76 77 78// constants won't change 79const int PIN02_R1_eMotor1 = 2; // Start 1 80const int PIN03_R2_eMotor2 = 3; // Start 2 81const int PIN04_R3_Ignition = 4; // Ignition 82const int PIN05_R4_StartFuel = 5; // Fuel Start 83const int PIN10_R5_RunFuel = 10; // Fuel Run 84const int PIN11_R6_Boost = 11; // Boost Pump 85 86const int PIN06_Overspeed = 6; // Over Speed 87const int PIN07_NormalRPM = 7; // Normal RPM 88const int PIN08_NormalOil = 8; // Oil Pressure OK 89const int PIN09_Centrifuge = 9; // Starter CuttOff 90const int PIN12_StartBtn = 12; // START 91 92const int PINA0_RPM = A0; // RPM 93const int PINA1_Temp = A1; // Exhaust Temperature 94const int PINA2_Buttons = A2; // Buttons 95 96char newtext[]="123"; 97 98 99void directWrite(uint8_t pin, uint8_t value); 100 101struct PinInfo { 102 volatile uint8_t *reg; 103 uint8_t mask; 104}; 105const PinInfo unoPins[] = { 106 {&PORTD, (uint8_t) 0b11111110}, 107 {&PORTD, (uint8_t) 0b11111101}, 108 {&PORTD, (uint8_t) 0b11111011}, 109 {&PORTD, (uint8_t) 0b11110111}, 110 {&PORTD, (uint8_t) 0b11101111}, 111 {&PORTD, (uint8_t) 0b11011111}, 112 {&PORTD, (uint8_t) 0b10111111}, 113 {&PORTD, (uint8_t) 0b01111111}, 114 {&PORTB, (uint8_t) 0b11111110}, 115 {&PORTB, (uint8_t) 0b11111101}, 116 {&PORTB, (uint8_t) 0b11111011}, 117 {&PORTB, (uint8_t) 0b11110111}, 118 {&PORTB, (uint8_t) 0b11101111}, 119 {&PORTB, (uint8_t) 0b11011111}, 120 {&PORTC, (uint8_t) 0b11111110}, 121 {&PORTC, (uint8_t) 0b11111101}, 122 {&PORTC, (uint8_t) 0b11111011}, 123 {&PORTC, (uint8_t) 0b11110111}, 124 {&PORTC, (uint8_t) 0b11101111}, 125 {&PORTC, (uint8_t) 0b11011111}, 126}; 127 128 129 130// the setup function runs once when you press reset or power the board 131void setup() { 132 Serial.begin(115200); 133 // 134 Wire.begin(); // join i2c bus (address optional for master) 135 //Wire.delay(200); 136 sensors.begin(); // Thermocouple 137 138 pinMode(PIN02_R1_eMotor1, OUTPUT); 139 pinMode(PIN03_R2_eMotor2, OUTPUT); 140 pinMode(PIN04_R3_Ignition, OUTPUT); 141 pinMode(PIN05_R4_StartFuel, OUTPUT); 142 pinMode(PIN10_R5_RunFuel, OUTPUT); 143 pinMode(PIN11_R6_Boost, OUTPUT); 144 145 pinMode(PIN06_Overspeed, INPUT_PULLUP); 146 pinMode(PIN07_NormalRPM, INPUT_PULLUP); 147 pinMode(PIN08_NormalOil, INPUT_PULLUP); 148 pinMode(PIN09_Centrifuge, INPUT_PULLUP); 149 pinMode(PIN12_StartBtn, INPUT_PULLUP); 150 151 pinMode(PINA0_RPM, INPUT); // RPM 152 pinMode(PINA1_Temp, INPUT); // Temperature 153 pinMode(PINA2_Buttons, INPUT); // buttons 154 155 // initialize digital pin as an output. (Default to High will disable relay) 156 //digitalWrite(PIN02_R1_eMotor1, HIGH); 157 //digitalWrite(PIN03_R2_eMotor2, HIGH); 158 //digitalWrite(PIN04_R3_Ignition, HIGH); 159 //digitalWrite(PIN05_R4_StartFuel, HIGH); 160 //digitalWrite(PIN10_R5_RunFuel, HIGH); 161 //digitalWrite(PIN11_R6_Boost, HIGH); 162 163 directWrite(PIN02_R1_eMotor1, HIGH); 164 directWrite(PIN03_R2_eMotor2, HIGH); 165 directWrite(PIN04_R3_Ignition, HIGH); 166 directWrite(PIN05_R4_StartFuel, HIGH); 167 directWrite(PIN10_R5_RunFuel, HIGH); 168 directWrite(PIN11_R6_Boost, HIGH); 169 170 //const unsigned short int SW = 4; 171 // may only work on pin 2/3 172 //attachInterrupt(digitalPinToInterrupt(SW_PIN13_1), changeLock, FALLING); 173 174 //delay(1000); 175 //Serial.println(digitalRead(PIN06_Overspeed)); 176 //Serial.println(digitalRead(PIN08_NormalOil)); 177 InfoMessage("Controller Startup",true); 178 // default centrifuge to Nc 179 DisplayUpdate(13,"",0); 180 // 181 // wait for Display to Initialise 182 delay(5000); 183 // 184 //// 185 //// Get any Slave data eg Version info or ready ! 186 //Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 187 //while (Wire.available()) { // slave may send less than requested 188 // char c = Wire.read(); // receive a byte as character 189 // Serial.print(c); // print the character 190 // } 191} 192 193// 194// the loop function runs over and over again forever 195void loop() { 196// 197// 1 second interval Timer 198 if ((((millis()-c)/1000) > l_time) && (start==false)) 199 { 200 l_time=((millis()-c)/1000); 201 GetTemperature(); 202 } 203 // 204 // Read Engine Sensors 205 // ========================================================= 206 if (Debug==false) 207 { 208 //Sence_Temp=analogRead(PINA1_Temp); 209 bool BitCheck; 210 211 // Over Speed (No false) 212 //if (digitalRead(PIN06_Overspeed)==LOW){Sence_OverSpeed=true;} else {Sence_OverSpeed=false;} 213 BitCheck=digitalRead(PIN06_Overspeed); 214 if (BitCheck==LOW && Sence_OverSpeed==false) 215 {Sence_OverSpeed=true;DisplayUpdate(12,"",0);} 216 else if (BitCheck==HIGH && Sence_OverSpeed==true) 217 {Sence_OverSpeed=false;DisplayUpdate(12,"",1);} 218 219 // Normal RPM (No false) 220 BitCheck=digitalRead(PIN07_NormalRPM); 221 if (BitCheck==LOW && Sence_SpeedOk==false) 222 {Sence_SpeedOk=true;DisplayUpdate(11,"",0);} 223 else if (BitCheck==HIGH && Sence_SpeedOk==true) 224 {Sence_SpeedOk=false;DisplayUpdate(11,"",1);} 225 226 // Oil Pressure (No false) 227 BitCheck=digitalRead(PIN08_NormalOil); 228 if (BitCheck==LOW && Sence_OilOk==false) 229 {Sence_OilOk=true;DisplayUpdate(10,"",0);} 230 else if (BitCheck==HIGH && Sence_OilOk==true) 231 {Sence_OilOk=false;DisplayUpdate(10,"",1);} 232 233 // Note Cetrifuge is Fliped (Nc false) 234 BitCheck=digitalRead(PIN09_Centrifuge); 235 if (BitCheck==LOW && Sence_OpenCentrifuge==true) 236 {Sence_OpenCentrifuge=false;DisplayUpdate(13,"",1);} 237 else if (BitCheck==HIGH && Sence_OpenCentrifuge==false) 238 {Sence_OpenCentrifuge=true;DisplayUpdate(13,"",0);} 239 // 240 //if (Sence_SpeedOk==true) {InfoMessage("speed ok");} 241 //DisplayUpdate(10,"",0); 242 243 } 244 // 245 // Read Analogue Buttons 246 ReadBtn=analogRead(PINA2_Buttons); 247 //filter out any noise by setting a time buffer 248 //Serial.println(ReadBtn); 249 if ((millis() - lastDebounceTime) > debounceDelay ) 250 { 251 Btn=ReadBtn; 252 //InfoMessage("Press " +(String)ReadBtn); 253 // 254 if (start==false) 255 { 256 //if (Btn <100) {FalseStart=false;ColdScroll=false;} 257 if (Btn <100 && (FalseStart==true || ColdScroll==true)){InfoMessage("Normal Start",true);FalseStart=false;ColdScroll=false;} 258 259 if (Btn >100 && Btn <300 && FalseStart==false){InfoMessage("False Start",true);FalseStart=true;ColdScroll=false;} 260 if (Btn >300 && Btn <500 && ColdScroll==false){InfoMessage("ColdScroll",true);FalseStart=false;ColdScroll=true;} 261 if (Btn >500 && Btn <750){InfoMessage("Test Spare"+(String)ReadBtn,true);} 262 if (Btn >750 && Btn <950) 263 { 264 // 265 DisplayUpdate(3,"",0) ; // Reset Display 266 // 267 Reset_Engine(); 268 //InfoMessage("Ready",true); 269 start=false; 270 } 271 } 272 else 273 { 274 // Stop button press while starting/running 275 if (Btn >950) 276 { 277 c = 0; 278 start=false; 279 Shutdown(); 280 //newtext = "ab"; 281//https://forum.arduino.cc/t/tricks-to-reduce-compiled-size/43560/40 282 283 InfoMessage("Stop "+(String)ReadBtn,true); 284 } 285 //Serial.println(Btn); 286 } 287 //ReadBtn=0; 288 lastDebounceTime = millis(); 289 } 290 291 // 292 // Start Button Press for 3 sec 293 // ====================================================================== 294 if (digitalRead(PIN12_StartBtn)==LOW && start == false && Sence_OverSpeed==false) 295 { 296 // add delay to allow any Analog reads to stabalise 297 delay(50); 298 // 299 if (BtnHeld==false){BtnHeld=true;StartupDebounceTime = millis();} 300 // 301 if ((millis() - StartupDebounceTime) > 2000 and BtnHeld==true) 302 { 303 BtnHeld=false; 304 StartupDebounceTime = millis(); 305 // 306 c = millis(); // call before EngineReset 307 Reset_Engine(); 308 //DisplayUpdate(3," ",0); // Reset Display 309 // 310 311 if (FalseStart==false && ColdScroll==false) {InfoMessage("Launch Start",true);} 312 else if (FalseStart==true) { InfoMessage("False Start",true); } 313 else if (ColdScroll==true) { InfoMessage("Cold Scroll",true); } 314 // 315 delay(50); 316 start = true; 317 DisplayUpdate(1,"",0); 318 c = millis(); 319 // 320 // Boost pump is allways enabled, (notifies the diags we are running) 321 R6_Boost= true; 322 //digitalWrite(PIN11_R6_Boost, LOW); 323 directWrite(PIN11_R6_Boost, LOW); 324 DisplayUpdate(14,"",0); 325 326 InfoMessage("R6, Boost Pump On",true); 327 DisplayUpdate(1,"",0); 328 } 329 } 330 else 331 { 332 // No Press 333 BtnHeld=false; 334 //startupDebounceTime = millis(); 335 } 336 337 // 338 // Engine Launch 339 if (start==true) 340 // Read Engine Sensors and Status 341 // ===================================================== 342 { // Must allways monitor for STOP press 343 if (analogRead(PINA2_Buttons) >950) 344 { 345 c = 0; 346 start=false; 347 Shutdown(); 348 InfoMessage("Stop Button",true); 349 } 350 // 351 // Get Temperature 352 if ((millis() - c) == 8000){GetTemperature();} 353 if ((millis() - c) == 11000){GetTemperature();} 354 if ((((millis()-c)/1000) > l_time) && ((millis() - c) >= 15000) ) 355 { 356 l_time=((millis()-c)/1000); 357 GetTemperature(); 358 } 359 // 360 // Early initialisation tests 361 // Boost pump to pressure (5 Seconds) 362 if ((millis()-c) > 0 && (millis() - c) < 5000) 363 { 364 if (R6_Boost==false) 365 { 366 Reset_Engine(); 367 InfoMessage("BoostPump Disabled",true); 368 } 369 370 //if (Sence_OpenCentrifuge == true) 371 if (Sence_OpenCentrifuge == true) 372 { 373 Reset_Engine(); 374 InfoMessage("eMotor Centrifuge Fault",true); 375 } 376 if (Sence_OilOk == true) 377 { 378 Reset_Engine(); 379 InfoMessage("Oil Pressure Sensor Fault",true); 380 } 381 if (Sence_SpeedOk == true) 382 { 383 Reset_Engine(); 384 InfoMessage("Speed Sensor Fault",true); 385 } 386 if (Sence_OverSpeed == true) 387 { 388 Reset_Engine(); 389 InfoMessage("OverSpeed Sensor Fault",true); 390 } 391 392 } 393 // Relay R1, eStart #1 394 if ((millis() - c) >= 5000 && (millis() - c) <= 5020) 395 { 396 // eMotor Start #1 @5 sec 397 if (R1_eMotor == false) 398 { 399 R1_eMotor = true; 400 //digitalWrite(PIN02_R1_eMotor1, LOW); 401 directWrite(PIN02_R1_eMotor1, LOW); 402 InfoMessage("R1, eMotor1 Start",false); 403 } 404 // Relay R3, Ignition 405 if (R3_Ignition == false && ColdScroll==false && FalseStart==false) 406 { 407 R3_Ignition = true; 408 //digitalWrite(PIN04_R3_Ignition, LOW); 409 directWrite(PIN04_R3_Ignition, LOW); 410 InfoMessage("R3, Ignition On",false); 411 } 412 // Relay R4 Fuel Start 413 if (R4_FuelStart== false && ColdScroll==false )//&& FalseStart==false 414 { 415 R4_FuelStart= true; 416 //digitalWrite(PIN05_R4_StartFuel, LOW); 417 directWrite(PIN05_R4_StartFuel, LOW); 418 InfoMessage("R4, Fuel Start On",false); 419 } 420 } 421 // Serial.println(".."); 422 // Relay R5,Fuel Run 423 if ((millis() - c) >= 6000 && (millis() - c) <= 6020) 424 { 425 //Serial.println("-----------------------------------"); 426 // Fuel run @6 sec 427 if (R5_FuelRun == false && ColdScroll==false)//and FalseStart==false 428 { 429 R5_FuelRun = true; 430 //digitalWrite(PIN10_R5_RunFuel, LOW); 431 directWrite(PIN10_R5_RunFuel, LOW); 432 InfoMessage("R5, Fuel Run On",false); 433 } 434 } 435 436 // Relay R2, Starter2 437 if ((millis() - c) >= 6500 && (millis() - c) <= 6520 && R2_eMotor == false) 438 { // Full Amps to motor 439 //if (R2_eMotor == false) 440 // { 441 R2_eMotor = true; 442 //digitalWrite(PIN03_R2_eMotor2, LOW); 443 directWrite(PIN03_R2_eMotor2, LOW); 444 InfoMessage("R2, eMotor2 Start",false); 445 // } 446 } 447 // Relay R1 Starter1 448 if ((millis() - c) >= 6800 && R1_eMotor == true) 449 { 450 // Half motor Power Disable (Disabled to stop burnout if R2 Fails) 451 //if (R1_eMotor == true) 452 //{ 453 R1_eMotor = false; 454 //digitalWrite(PIN02_R1_eMotor1, HIGH); 455 directWrite(PIN02_R1_eMotor1, HIGH); 456 InfoMessage("R1, eMotor1 Disabled",false); 457 //} 458 } 459 460 // Realy R4,Starting Fuel & Relay R3, Ignition Coil 461 if ((millis() - c) >= 12000) 462 { 463 if (R4_FuelStart== true) 464 { 465 // Check tart Fuel has stoped @12 sec 466 R4_FuelStart= false; 467 //digitalWrite(PIN05_R4_StartFuel, HIGH); 468 directWrite(PIN05_R4_StartFuel, HIGH); 469 InfoMessage("R4, Fuel Start Off",false); 470 } 471 if (R3_Ignition==true) 472 { 473 // Check Ignition Off @12 Sec 474 R3_Ignition = false; 475 //digitalWrite(PIN04_R3_Ignition, HIGH); 476 directWrite(PIN04_R3_Ignition, HIGH); 477 InfoMessage("R3, Ignition Shutoff",false); 478 } 479 } 480 481 // 482 // Constant Monitoring From Here 483 // ======================================================================== 484 // Over Temperature (Any Time) 485 if (Sence_Temp >800 && start==true) 486 { 487 InfoMessage("Over Temperature",true); 488 Shutdown(); 489 } 490 491 // 492 // RPM Over Speed (Any Time after 20 sec) 493 if ((millis() - c) >= 20000 && start==true && Sence_OverSpeed==true) 494 { 495 InfoMessage("Over Speed",true); 496 Shutdown(); 497 } 498 499 // RPM not to speed after 20s 500 if ((millis() - c) >= 20000 && start==true && Sence_SpeedOk==false) 501 { 502//if (digitalRead(PIN_D8_NormalOil)==LOW){InfoMessage("Oil Signal ok -------------------");} 503//if (digitalRead(PIN_D7_NormalRPM)==LOW){InfoMessage("RPM Signal ok -------------------");} 504 InfoMessage("Low RPM Detection",true); 505 Shutdown(); 506 } 507 // Oil Pressure Low after 24s 508 if ((millis() - c) >= 24000 && start==true && Sence_OilOk==false && Sence_SpeedOk==true) 509 { 510//if (digitalRead(PIN_D8_NormalOil)==LOW){InfoMessage("Oil Signal ok -------------------");} 511//if (digitalRead(PIN_D7_NormalRPM)==LOW){InfoMessage("RPM Signal ok -------------------");} 512 InfoMessage("Oil Pressure Low",true); 513 Shutdown(); 514 } 515 516 // Sence_OpenCentrifuge after 20s 517 if ((millis() - c) >= 20000 && start==true && Sence_OpenCentrifuge==false) 518 { 519 InfoMessage("eMotor Centrifuge Error",true); 520 Shutdown(); 521 } 522 523 524 // Stop motor if centrifuge after 12s or max >20s 525 if ((millis() - c) >= 12000 && Sence_OpenCentrifuge==true && R2_eMotor==true && start==true) 526 { 527 R2_eMotor =false; 528 //digitalWrite(PIN03_R2_eMotor2, HIGH); 529 directWrite(PIN03_R2_eMotor2, HIGH); 530 InfoMessage("eMotor2 disconnect",true); 531 } 532 if ((millis() - c) >= 20000 && start==true && R2_eMotor ==true) 533 { 534 R2_eMotor =false; 535 //digitalWrite(PIN03_R2_eMotor2, HIGH); 536 directWrite(PIN03_R2_eMotor2, HIGH); 537 InfoMessage("eMotor2 disconnect",true); 538 } 539 } 540 541// End Of Loop 542} 543 544 545bool GetTemperature() 546{ 547 sensors.requestTemperatures(); // Send the command to get temperatures 548 Sence_Temp=sensors.getTempCByIndex(0); 549 DisplayUpdate(6,"",Sence_Temp); 550 } 551 552bool Shutdown() 553 { 554 c = 0; 555 Reset_Engine(); 556 DisplayUpdate(2," ",0); // Stop Timer 557 } 558 559bool Reset_Engine() 560 { 561 // Shutdown Engine 562 start = false; 563 //c = 0; 564 565 //Sence_Temp=0; 566 Sence_OverSpeed = false; 567 Sence_SpeedOk = false; 568 Sence_OilOk = false; 569 Sence_OpenCentrifuge =false; 570 571 directWrite(PIN02_R1_eMotor1, HIGH); R1_eMotor = false; 572 directWrite(PIN03_R2_eMotor2, HIGH); R2_eMotor = false; 573 directWrite(PIN04_R3_Ignition, HIGH); R3_Ignition = false; 574 directWrite(PIN05_R4_StartFuel, HIGH); R4_FuelStart = false; 575 directWrite(PIN10_R5_RunFuel, HIGH); R5_FuelRun = false; 576 directWrite(PIN11_R6_Boost, HIGH); R6_Boost =false; 577 578 579 580 581 582 // reset of display will clear all sensors 583//DisplayUpdate(3,"",0) ; 584 585 delay(200); 586 InfoMessage("Engine Reset",false); 587 return true; 588 } 589// 590// 591void InfoMessage(String NewText,boolean Display) 592 { 593 //Serial.println( (String) (millis() - c) +":" +NewText); 594 // 595 //DisplayUpdate(4,NewText,0) ; // 4 Message out to Display 596 597 if (Display==true) 598 { 599 // TFT output 600 DisplayUpdate(4,NewText,0) ; // 4 Message out to Display 601 } 602 else 603 { 604 // Debug only 605 Serial.println(NewText); 606 } 607 } 608// 609//https://docs.arduino.cc/library-examples/wire-library/ControllerWriter 610void DisplayUpdate(int CommandNo,String Buffer,int Val) 611{ 612 int mask = 0xFF; 613 Serial.println("Command:" +(String)CommandNo+ " "+Buffer +" "+(String)Val); 614 //return; 615 Wire.beginTransmission(8); // transmit to device #8 616 Wire.write(CommandNo); // sends one byte Command 1-255 617 Wire.write(Buffer.c_str()); // Send Buffer 618 //Wire.write(""); // Terminate Buffer with "" 619 Wire.write(Val & mask); // sends one byte Val 620 Wire.write(Val >>8); // sends one byte Val 621 Wire.endTransmission(); // stop transmitting 622 //Serial.println("Done"); 623 } 624 625 626void setpin(int Pin) 627 { 628 //https://arduino.stackexchange.com/questions/44531/arduino-esp8266-direct-fast-control-of-the-digital-pins 629 bitSet(PORTD,Pin); 630 bitSet(PORTD,Pin); 631 bitSet(PORTD,Pin); 632 bitSet(PORTD,Pin); 633 634 } 635 636 637void directWrite(uint8_t pin, uint8_t value) { 638 if (value == 0) { 639 *(unoPins[pin].reg) &= unoPins[pin].mask; 640 } else { 641 *(unoPins[pin].reg) |= ~unoPins[pin].mask; 642 } 643} 644 645
Main Control System
arduino
I have never done this before and if i were to have another go, im sure i would do better. That said it does work and to test it i built another diagnostics box that responds the same way the engine would (Stops the missus shouting at me making all that noise) Its basically a huge time dependant loop I have used direct hardware ports to trigger the relay as talking to the SPI bus takes time and the Thermocouple read is slow (i may have to re look at that)
1/* 2 AI-9 APU Gas Turbine Launch (Main Control Panel) 3===================================================================== 4 5 Created 22/08/2021 6 by Derek Beacroft UK 7 8// Run fuel & Ignition 9// False Start Fuel No Ignition 10// Cold Scroll No Fuel No Ignition 11 12Display on I2C Line 13 CommandNo,"buff",Val 14 1,"",0 // Start 15 2,"",0 // Stop 16 3,"",0 // Reset Display 17 4,"message",0 // Display new message 18 5, 19 6,xxx // Temperature 20 7,xxx // Speed 21 8, 22 9, 23 10,"",01 // Over Speed 24 11,"",01 // Normal Speed 25 12,"",01 // Oil Pressure 26 13,"",01 // Centrifuge 27 14,"",01 // Boost Pump 28 29*/ 30#include <Wire.h> 31#include <OneWire.h> 32#include <DallasTemperature.h> 33 34 35// Data wire is plugged into port 3 on Arduino 36#define ONE_WIRE_BUS 15 // 15=A1 37// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 38OneWire oneWire(ONE_WIRE_BUS); 39// Pass our oneWire reference to Dallas Temperature. 40DallasTemperature sensors(&oneWire); 41 42 43#define Debug (bool) false // 44int l_time = millis()/1000; 45 46bool start = false; 47bool R1_eMotor = false; 48bool R2_eMotor = false; 49bool R3_Ignition = false; 50bool R4_FuelStart = false; 51bool R5_FuelRun= false; 52bool R6_Boost = false; 53 54bool Sence_OpenCentrifuge =false; // eMotor Switch Nc (default open until connected to engine) 55bool Sence_SpeedOk = false; // Fuel Pressure ok 56bool Sence_OilOk = false; // Oil Pressure ok 57bool Sence_OverSpeed = false; // Fuel Pressure over 58 59bool ColdScroll = false; 60bool FalseStart = false; 61bool BtnHeld = false; 62 63 64int val =0; 65int Value =0; 66int Sence_Temp=240; 67int Btn =0; 68unsigned int ReadBtn; 69 70unsigned long c = 0; 71unsigned long Temperature = 25; 72 73long StartupDebounceTime= 0; // the last time the output pin was toggled 74long lastDebounceTime = 0; // the last time the output pin was toggled 75#define debounceDelay (uint8_t) 400 // the debounce time; increase if the output flickers 76 77 78// constants won't change 79const int PIN02_R1_eMotor1 = 2; // Start 1 80const int PIN03_R2_eMotor2 = 3; // Start 2 81const int PIN04_R3_Ignition = 4; // Ignition 82const int PIN05_R4_StartFuel = 5; // Fuel Start 83const int PIN10_R5_RunFuel = 10; // Fuel Run 84const int PIN11_R6_Boost = 11; // Boost Pump 85 86const int PIN06_Overspeed = 6; // Over Speed 87const int PIN07_NormalRPM = 7; // Normal RPM 88const int PIN08_NormalOil = 8; // Oil Pressure OK 89const int PIN09_Centrifuge = 9; // Starter CuttOff 90const int PIN12_StartBtn = 12; // START 91 92const int PINA0_RPM = A0; // RPM 93const int PINA1_Temp = A1; // Exhaust Temperature 94const int PINA2_Buttons = A2; // Buttons 95 96char newtext[]="123"; 97 98 99void directWrite(uint8_t pin, uint8_t value); 100 101struct PinInfo { 102 volatile uint8_t *reg; 103 uint8_t mask; 104}; 105const PinInfo unoPins[] = { 106 {&PORTD, (uint8_t) 0b11111110}, 107 {&PORTD, (uint8_t) 0b11111101}, 108 {&PORTD, (uint8_t) 0b11111011}, 109 {&PORTD, (uint8_t) 0b11110111}, 110 {&PORTD, (uint8_t) 0b11101111}, 111 {&PORTD, (uint8_t) 0b11011111}, 112 {&PORTD, (uint8_t) 0b10111111}, 113 {&PORTD, (uint8_t) 0b01111111}, 114 {&PORTB, (uint8_t) 0b11111110}, 115 {&PORTB, (uint8_t) 0b11111101}, 116 {&PORTB, (uint8_t) 0b11111011}, 117 {&PORTB, (uint8_t) 0b11110111}, 118 {&PORTB, (uint8_t) 0b11101111}, 119 {&PORTB, (uint8_t) 0b11011111}, 120 {&PORTC, (uint8_t) 0b11111110}, 121 {&PORTC, (uint8_t) 0b11111101}, 122 {&PORTC, (uint8_t) 0b11111011}, 123 {&PORTC, (uint8_t) 0b11110111}, 124 {&PORTC, (uint8_t) 0b11101111}, 125 {&PORTC, (uint8_t) 0b11011111}, 126}; 127 128 129 130// the setup function runs once when you press reset or power the board 131void setup() { 132 Serial.begin(115200); 133 // 134 Wire.begin(); // join i2c bus (address optional for master) 135 //Wire.delay(200); 136 sensors.begin(); // Thermocouple 137 138 pinMode(PIN02_R1_eMotor1, OUTPUT); 139 pinMode(PIN03_R2_eMotor2, OUTPUT); 140 pinMode(PIN04_R3_Ignition, OUTPUT); 141 pinMode(PIN05_R4_StartFuel, OUTPUT); 142 pinMode(PIN10_R5_RunFuel, OUTPUT); 143 pinMode(PIN11_R6_Boost, OUTPUT); 144 145 pinMode(PIN06_Overspeed, INPUT_PULLUP); 146 pinMode(PIN07_NormalRPM, INPUT_PULLUP); 147 pinMode(PIN08_NormalOil, INPUT_PULLUP); 148 pinMode(PIN09_Centrifuge, INPUT_PULLUP); 149 pinMode(PIN12_StartBtn, INPUT_PULLUP); 150 151 pinMode(PINA0_RPM, INPUT); // RPM 152 pinMode(PINA1_Temp, INPUT); // Temperature 153 pinMode(PINA2_Buttons, INPUT); // buttons 154 155 // initialize digital pin as an output. (Default to High will disable relay) 156 //digitalWrite(PIN02_R1_eMotor1, HIGH); 157 //digitalWrite(PIN03_R2_eMotor2, HIGH); 158 //digitalWrite(PIN04_R3_Ignition, HIGH); 159 //digitalWrite(PIN05_R4_StartFuel, HIGH); 160 //digitalWrite(PIN10_R5_RunFuel, HIGH); 161 //digitalWrite(PIN11_R6_Boost, HIGH); 162 163 directWrite(PIN02_R1_eMotor1, HIGH); 164 directWrite(PIN03_R2_eMotor2, HIGH); 165 directWrite(PIN04_R3_Ignition, HIGH); 166 directWrite(PIN05_R4_StartFuel, HIGH); 167 directWrite(PIN10_R5_RunFuel, HIGH); 168 directWrite(PIN11_R6_Boost, HIGH); 169 170 //const unsigned short int SW = 4; 171 // may only work on pin 2/3 172 //attachInterrupt(digitalPinToInterrupt(SW_PIN13_1), changeLock, FALLING); 173 174 //delay(1000); 175 //Serial.println(digitalRead(PIN06_Overspeed)); 176 //Serial.println(digitalRead(PIN08_NormalOil)); 177 InfoMessage("Controller Startup",true); 178 // default centrifuge to Nc 179 DisplayUpdate(13,"",0); 180 // 181 // wait for Display to Initialise 182 delay(5000); 183 // 184 //// 185 //// Get any Slave data eg Version info or ready ! 186 //Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 187 //while (Wire.available()) { // slave may send less than requested 188 // char c = Wire.read(); // receive a byte as character 189 // Serial.print(c); // print the character 190 // } 191} 192 193// 194// the loop function runs over and over again forever 195void loop() { 196// 197// 1 second interval Timer 198 if ((((millis()-c)/1000) > l_time) && (start==false)) 199 { 200 l_time=((millis()-c)/1000); 201 GetTemperature(); 202 } 203 // 204 // Read Engine Sensors 205 // ========================================================= 206 if (Debug==false) 207 { 208 //Sence_Temp=analogRead(PINA1_Temp); 209 bool BitCheck; 210 211 // Over Speed (No false) 212 //if (digitalRead(PIN06_Overspeed)==LOW){Sence_OverSpeed=true;} else {Sence_OverSpeed=false;} 213 BitCheck=digitalRead(PIN06_Overspeed); 214 if (BitCheck==LOW && Sence_OverSpeed==false) 215 {Sence_OverSpeed=true;DisplayUpdate(12,"",0);} 216 else if (BitCheck==HIGH && Sence_OverSpeed==true) 217 {Sence_OverSpeed=false;DisplayUpdate(12,"",1);} 218 219 // Normal RPM (No false) 220 BitCheck=digitalRead(PIN07_NormalRPM); 221 if (BitCheck==LOW && Sence_SpeedOk==false) 222 {Sence_SpeedOk=true;DisplayUpdate(11,"",0);} 223 else if (BitCheck==HIGH && Sence_SpeedOk==true) 224 {Sence_SpeedOk=false;DisplayUpdate(11,"",1);} 225 226 // Oil Pressure (No false) 227 BitCheck=digitalRead(PIN08_NormalOil); 228 if (BitCheck==LOW && Sence_OilOk==false) 229 {Sence_OilOk=true;DisplayUpdate(10,"",0);} 230 else if (BitCheck==HIGH && Sence_OilOk==true) 231 {Sence_OilOk=false;DisplayUpdate(10,"",1);} 232 233 // Note Cetrifuge is Fliped (Nc false) 234 BitCheck=digitalRead(PIN09_Centrifuge); 235 if (BitCheck==LOW && Sence_OpenCentrifuge==true) 236 {Sence_OpenCentrifuge=false;DisplayUpdate(13,"",1);} 237 else if (BitCheck==HIGH && Sence_OpenCentrifuge==false) 238 {Sence_OpenCentrifuge=true;DisplayUpdate(13,"",0);} 239 // 240 //if (Sence_SpeedOk==true) {InfoMessage("speed ok");} 241 //DisplayUpdate(10,"",0); 242 243 } 244 // 245 // Read Analogue Buttons 246 ReadBtn=analogRead(PINA2_Buttons); 247 //filter out any noise by setting a time buffer 248 //Serial.println(ReadBtn); 249 if ((millis() - lastDebounceTime) > debounceDelay ) 250 { 251 Btn=ReadBtn; 252 //InfoMessage("Press " +(String)ReadBtn); 253 // 254 if (start==false) 255 { 256 //if (Btn <100) {FalseStart=false;ColdScroll=false;} 257 if (Btn <100 && (FalseStart==true || ColdScroll==true)){InfoMessage("Normal Start",true);FalseStart=false;ColdScroll=false;} 258 259 if (Btn >100 && Btn <300 && FalseStart==false){InfoMessage("False Start",true);FalseStart=true;ColdScroll=false;} 260 if (Btn >300 && Btn <500 && ColdScroll==false){InfoMessage("ColdScroll",true);FalseStart=false;ColdScroll=true;} 261 if (Btn >500 && Btn <750){InfoMessage("Test Spare"+(String)ReadBtn,true);} 262 if (Btn >750 && Btn <950) 263 { 264 // 265 DisplayUpdate(3,"",0) ; // Reset Display 266 // 267 Reset_Engine(); 268 //InfoMessage("Ready",true); 269 start=false; 270 } 271 } 272 else 273 { 274 // Stop button press while starting/running 275 if (Btn >950) 276 { 277 c = 0; 278 start=false; 279 Shutdown(); 280 //newtext = "ab"; 281//https://forum.arduino.cc/t/tricks-to-reduce-compiled-size/43560/40 282 283 InfoMessage("Stop "+(String)ReadBtn,true); 284 } 285 //Serial.println(Btn); 286 } 287 //ReadBtn=0; 288 lastDebounceTime = millis(); 289 } 290 291 // 292 // Start Button Press for 3 sec 293 // ====================================================================== 294 if (digitalRead(PIN12_StartBtn)==LOW && start == false && Sence_OverSpeed==false) 295 { 296 // add delay to allow any Analog reads to stabalise 297 delay(50); 298 // 299 if (BtnHeld==false){BtnHeld=true;StartupDebounceTime = millis();} 300 // 301 if ((millis() - StartupDebounceTime) > 2000 and BtnHeld==true) 302 { 303 BtnHeld=false; 304 StartupDebounceTime = millis(); 305 // 306 c = millis(); // call before EngineReset 307 Reset_Engine(); 308 //DisplayUpdate(3," ",0); // Reset Display 309 // 310 311 if (FalseStart==false && ColdScroll==false) {InfoMessage("Launch Start",true);} 312 else if (FalseStart==true) { InfoMessage("False Start",true); } 313 else if (ColdScroll==true) { InfoMessage("Cold Scroll",true); } 314 // 315 delay(50); 316 start = true; 317 DisplayUpdate(1,"",0); 318 c = millis(); 319 // 320 // Boost pump is allways enabled, (notifies the diags we are running) 321 R6_Boost= true; 322 //digitalWrite(PIN11_R6_Boost, LOW); 323 directWrite(PIN11_R6_Boost, LOW); 324 DisplayUpdate(14,"",0); 325 326 InfoMessage("R6, Boost Pump On",true); 327 DisplayUpdate(1,"",0); 328 } 329 } 330 else 331 { 332 // No Press 333 BtnHeld=false; 334 //startupDebounceTime = millis(); 335 } 336 337 // 338 // Engine Launch 339 if (start==true) 340 // Read Engine Sensors and Status 341 // ===================================================== 342 { // Must allways monitor for STOP press 343 if (analogRead(PINA2_Buttons) >950) 344 { 345 c = 0; 346 start=false; 347 Shutdown(); 348 InfoMessage("Stop Button",true); 349 } 350 // 351 // Get Temperature 352 if ((millis() - c) == 8000){GetTemperature();} 353 if ((millis() - c) == 11000){GetTemperature();} 354 if ((((millis()-c)/1000) > l_time) && ((millis() - c) >= 15000) ) 355 { 356 l_time=((millis()-c)/1000); 357 GetTemperature(); 358 } 359 // 360 // Early initialisation tests 361 // Boost pump to pressure (5 Seconds) 362 if ((millis()-c) > 0 && (millis() - c) < 5000) 363 { 364 if (R6_Boost==false) 365 { 366 Reset_Engine(); 367 InfoMessage("BoostPump Disabled",true); 368 } 369 370 //if (Sence_OpenCentrifuge == true) 371 if (Sence_OpenCentrifuge == true) 372 { 373 Reset_Engine(); 374 InfoMessage("eMotor Centrifuge Fault",true); 375 } 376 if (Sence_OilOk == true) 377 { 378 Reset_Engine(); 379 InfoMessage("Oil Pressure Sensor Fault",true); 380 } 381 if (Sence_SpeedOk == true) 382 { 383 Reset_Engine(); 384 InfoMessage("Speed Sensor Fault",true); 385 } 386 if (Sence_OverSpeed == true) 387 { 388 Reset_Engine(); 389 InfoMessage("OverSpeed Sensor Fault",true); 390 } 391 392 } 393 // Relay R1, eStart #1 394 if ((millis() - c) >= 5000 && (millis() - c) <= 5020) 395 { 396 // eMotor Start #1 @5 sec 397 if (R1_eMotor == false) 398 { 399 R1_eMotor = true; 400 //digitalWrite(PIN02_R1_eMotor1, LOW); 401 directWrite(PIN02_R1_eMotor1, LOW); 402 InfoMessage("R1, eMotor1 Start",false); 403 } 404 // Relay R3, Ignition 405 if (R3_Ignition == false && ColdScroll==false && FalseStart==false) 406 { 407 R3_Ignition = true; 408 //digitalWrite(PIN04_R3_Ignition, LOW); 409 directWrite(PIN04_R3_Ignition, LOW); 410 InfoMessage("R3, Ignition On",false); 411 } 412 // Relay R4 Fuel Start 413 if (R4_FuelStart== false && ColdScroll==false )//&& FalseStart==false 414 { 415 R4_FuelStart= true; 416 //digitalWrite(PIN05_R4_StartFuel, LOW); 417 directWrite(PIN05_R4_StartFuel, LOW); 418 InfoMessage("R4, Fuel Start On",false); 419 } 420 } 421 // Serial.println(".."); 422 // Relay R5,Fuel Run 423 if ((millis() - c) >= 6000 && (millis() - c) <= 6020) 424 { 425 //Serial.println("-----------------------------------"); 426 // Fuel run @6 sec 427 if (R5_FuelRun == false && ColdScroll==false)//and FalseStart==false 428 { 429 R5_FuelRun = true; 430 //digitalWrite(PIN10_R5_RunFuel, LOW); 431 directWrite(PIN10_R5_RunFuel, LOW); 432 InfoMessage("R5, Fuel Run On",false); 433 } 434 } 435 436 // Relay R2, Starter2 437 if ((millis() - c) >= 6500 && (millis() - c) <= 6520 && R2_eMotor == false) 438 { // Full Amps to motor 439 //if (R2_eMotor == false) 440 // { 441 R2_eMotor = true; 442 //digitalWrite(PIN03_R2_eMotor2, LOW); 443 directWrite(PIN03_R2_eMotor2, LOW); 444 InfoMessage("R2, eMotor2 Start",false); 445 // } 446 } 447 // Relay R1 Starter1 448 if ((millis() - c) >= 6800 && R1_eMotor == true) 449 { 450 // Half motor Power Disable (Disabled to stop burnout if R2 Fails) 451 //if (R1_eMotor == true) 452 //{ 453 R1_eMotor = false; 454 //digitalWrite(PIN02_R1_eMotor1, HIGH); 455 directWrite(PIN02_R1_eMotor1, HIGH); 456 InfoMessage("R1, eMotor1 Disabled",false); 457 //} 458 } 459 460 // Realy R4,Starting Fuel & Relay R3, Ignition Coil 461 if ((millis() - c) >= 12000) 462 { 463 if (R4_FuelStart== true) 464 { 465 // Check tart Fuel has stoped @12 sec 466 R4_FuelStart= false; 467 //digitalWrite(PIN05_R4_StartFuel, HIGH); 468 directWrite(PIN05_R4_StartFuel, HIGH); 469 InfoMessage("R4, Fuel Start Off",false); 470 } 471 if (R3_Ignition==true) 472 { 473 // Check Ignition Off @12 Sec 474 R3_Ignition = false; 475 //digitalWrite(PIN04_R3_Ignition, HIGH); 476 directWrite(PIN04_R3_Ignition, HIGH); 477 InfoMessage("R3, Ignition Shutoff",false); 478 } 479 } 480 481 // 482 // Constant Monitoring From Here 483 // ======================================================================== 484 // Over Temperature (Any Time) 485 if (Sence_Temp >800 && start==true) 486 { 487 InfoMessage("Over Temperature",true); 488 Shutdown(); 489 } 490 491 // 492 // RPM Over Speed (Any Time after 20 sec) 493 if ((millis() - c) >= 20000 && start==true && Sence_OverSpeed==true) 494 { 495 InfoMessage("Over Speed",true); 496 Shutdown(); 497 } 498 499 // RPM not to speed after 20s 500 if ((millis() - c) >= 20000 && start==true && Sence_SpeedOk==false) 501 { 502//if (digitalRead(PIN_D8_NormalOil)==LOW){InfoMessage("Oil Signal ok -------------------");} 503//if (digitalRead(PIN_D7_NormalRPM)==LOW){InfoMessage("RPM Signal ok -------------------");} 504 InfoMessage("Low RPM Detection",true); 505 Shutdown(); 506 } 507 // Oil Pressure Low after 24s 508 if ((millis() - c) >= 24000 && start==true && Sence_OilOk==false && Sence_SpeedOk==true) 509 { 510//if (digitalRead(PIN_D8_NormalOil)==LOW){InfoMessage("Oil Signal ok -------------------");} 511//if (digitalRead(PIN_D7_NormalRPM)==LOW){InfoMessage("RPM Signal ok -------------------");} 512 InfoMessage("Oil Pressure Low",true); 513 Shutdown(); 514 } 515 516 // Sence_OpenCentrifuge after 20s 517 if ((millis() - c) >= 20000 && start==true && Sence_OpenCentrifuge==false) 518 { 519 InfoMessage("eMotor Centrifuge Error",true); 520 Shutdown(); 521 } 522 523 524 // Stop motor if centrifuge after 12s or max >20s 525 if ((millis() - c) >= 12000 && Sence_OpenCentrifuge==true && R2_eMotor==true && start==true) 526 { 527 R2_eMotor =false; 528 //digitalWrite(PIN03_R2_eMotor2, HIGH); 529 directWrite(PIN03_R2_eMotor2, HIGH); 530 InfoMessage("eMotor2 disconnect",true); 531 } 532 if ((millis() - c) >= 20000 && start==true && R2_eMotor ==true) 533 { 534 R2_eMotor =false; 535 //digitalWrite(PIN03_R2_eMotor2, HIGH); 536 directWrite(PIN03_R2_eMotor2, HIGH); 537 InfoMessage("eMotor2 disconnect",true); 538 } 539 } 540 541// End Of Loop 542} 543 544 545bool GetTemperature() 546{ 547 sensors.requestTemperatures(); // Send the command to get temperatures 548 Sence_Temp=sensors.getTempCByIndex(0); 549 DisplayUpdate(6,"",Sence_Temp); 550 } 551 552bool Shutdown() 553 { 554 c = 0; 555 Reset_Engine(); 556 DisplayUpdate(2," ",0); // Stop Timer 557 } 558 559bool Reset_Engine() 560 { 561 // Shutdown Engine 562 start = false; 563 //c = 0; 564 565 //Sence_Temp=0; 566 Sence_OverSpeed = false; 567 Sence_SpeedOk = false; 568 Sence_OilOk = false; 569 Sence_OpenCentrifuge =false; 570 571 directWrite(PIN02_R1_eMotor1, HIGH); R1_eMotor = false; 572 directWrite(PIN03_R2_eMotor2, HIGH); R2_eMotor = false; 573 directWrite(PIN04_R3_Ignition, HIGH); R3_Ignition = false; 574 directWrite(PIN05_R4_StartFuel, HIGH); R4_FuelStart = false; 575 directWrite(PIN10_R5_RunFuel, HIGH); R5_FuelRun = false; 576 directWrite(PIN11_R6_Boost, HIGH); R6_Boost =false; 577 578 579 580 581 582 // reset of display will clear all sensors 583//DisplayUpdate(3,"",0) ; 584 585 delay(200); 586 InfoMessage("Engine Reset",false); 587 return true; 588 } 589// 590// 591void InfoMessage(String NewText,boolean Display) 592 { 593 //Serial.println( (String) (millis() - c) +":" +NewText); 594 // 595 //DisplayUpdate(4,NewText,0) ; // 4 Message out to Display 596 597 if (Display==true) 598 { 599 // TFT output 600 DisplayUpdate(4,NewText,0) ; // 4 Message out to Display 601 } 602 else 603 { 604 // Debug only 605 Serial.println(NewText); 606 } 607 } 608// 609//https://docs.arduino.cc/library-examples/wire-library/ControllerWriter 610void DisplayUpdate(int CommandNo,String Buffer,int Val) 611{ 612 int mask = 0xFF; 613 Serial.println("Command:" +(String)CommandNo+ " "+Buffer +" "+(String)Val); 614 //return; 615 Wire.beginTransmission(8); // transmit to device #8 616 Wire.write(CommandNo); // sends one byte Command 1-255 617 Wire.write(Buffer.c_str()); // Send Buffer 618 //Wire.write(""); // Terminate Buffer with "" 619 Wire.write(Val & mask); // sends one byte Val 620 Wire.write(Val >>8); // sends one byte Val 621 Wire.endTransmission(); // stop transmitting 622 //Serial.println("Done"); 623 } 624 625 626void setpin(int Pin) 627 { 628 //https://arduino.stackexchange.com/questions/44531/arduino-esp8266-direct-fast-control-of-the-digital-pins 629 bitSet(PORTD,Pin); 630 bitSet(PORTD,Pin); 631 bitSet(PORTD,Pin); 632 bitSet(PORTD,Pin); 633 634 } 635 636 637void directWrite(uint8_t pin, uint8_t value) { 638 if (value == 0) { 639 *(unoPins[pin].reg) &= unoPins[pin].mask; 640 } else { 641 *(unoPins[pin].reg) |= ~unoPins[pin].mask; 642 } 643} 644 645
Display Controler
arduino
This created the main display UI, has a small update window to show messages, Run timer and Relay status And before im flooded with "why not do it this way" etc, its because i did and i do it for pleasure.
1/* 2 AI-9 APU Gas Turbine Display 3 ===================================================================== 4 5 6 Created 22/08/2021 7 by Derek Beacroft 8 9Display on I2C Line 10 11 CommandNo,"buff",Val 12 1,"",0 // Start 13 2,"",0 // Stop 14 15 3,"",0 // Reset Display 16 4,"message",0 // Display new message 17 18 5, 19 6,xxx // Temperature 20 7,xxx // Speed 21 8, 22 23 9, 24 10,"",01 // Over Speed 25 11,"",01 // Normal Speed 26 12,"",01 27 // Oil Pressure 28 13,"",01 // Centrifuge 29 14,"",01 // Boost 30 Pump 31 32 free 399 33 34*/ 35#include <Wire.h> 36// 37// 38#include 39 <LCDWIKI_GUI.h> //Core graphics library 40#include <LCDWIKI_SPI.h> //Hardware-specific 41 library 42//paramters define 43#define MODEL ILI9488_18 44// 45#include <arduino-timer.h> 46//auto 47 timer = timer_create_default(); // create a timer with default settings 48 49 50//https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html 51 52 53 54 55//#define 56 CS A2 57//#define CD A3 58//#define RST A1 59//#define LED A0 //if 60 you don't need to control the LED pin,you should set it to -1 and set it to 3.3V 61 62#define 63 CS A2 64#define CD A0 65#define RST A1 66#define LED A3 //if you 67 don't need to control the LED pin,you should set it to -1 and set it to 3.3V 68 69#define 70 Rad (float) 0.01745329 71 72unsigned long RunTime = 0; 73bool SystemRun = false; 74bool 75 Dev = false; 76 77//the definiens of hardware spi mode as follow: 78//if the 79 IC model is known or the modules is unreadable,you can use this constructed function 80LCDWIKI_SPI 81 my_lcd(MODEL,CS,CD,RST,LED); //model,cs,dc,reset,led 82 83//define some colour 84 values 85#define BLACK 0x0000 86#define BLUE 0x001F 87#define RED 0xF800 88#define 89 GREEN 0x07E0 90#define CYAN 0x07FF 91#define MAGENTA 0xF81F 92#define YELLOW 93 0xFFE0 94#define WHITE 0xFFFF 95 96//#define Op (String) "Oil Pressure:" 97//#define 98 Space (String) " " 99 100int Tm; 101int Ts; 102int TempPointer 103 = 300; // Initial point of Temp gauge 104//bool Ready = false; // 105 Display Initialised and Ready 106bool DisplayReady = false; // Display 107 Initialised and Ready 108 109String Line1=""; 110String Line2="";//"Initialising"; 111//String 112 Line3="AI-9 Control v1.0"; 113String Line3=""; 114String Line4=""; 115//String 116 Line5=""; 117//char abc(20); 118 119 120 121 122 123void setup() { 124 // 125 126 //pinMode(LED, OUTPUT); // TFT Backlite 127 //analogWrite(LED, 250); // 128 Power level (Max 3v) 129 Serial.begin(115200); // start serial for output 130 131 132 // 133 Wire.begin(8); // join i2c bus with address #8 134 135 //Wire.onRequest(requestEvent); // register outgoung event 136 Wire.onReceive(receiveEvent); 137 // register incommong event 138 139 my_lcd.Init_LCD(); 140 my_lcd.Fill_Screen(0x0); 141 142 //Serial.println("Init"); 143 144my_lcd.Led_control(true); 145 // 146 147 // left,top,left+,right+ 148 //mylcd.Fill_Screen(BLACK); 149 my_lcd.Set_Rotation(1); 150 151 my_lcd.Set_Text_Back_colour(BLACK); 152 my_lcd.Set_Text_colour(0xE000); 153 154 155 //my_lcd.Print_String("Initialising AI-9", 10, 10); 156 my_lcd.Set_Text_Size(4); 157 158 my_lcd.Print_String("RUN TIME", 10, 10); 159 my_lcd.Set_Text_Size(5); 160 161 my_lcd.Print_String("00:00", 30, 55); 162 163 my_lcd.Set_Text_Size(2); 164 165 my_lcd.Draw_Rectangle( 0, 0, 477, 317); 166 my_lcd.Draw_Rectangle( 1, 1, 476, 167 316); 168 my_lcd.Draw_Rectangle( 2, 2, 475, 315); 169 170 my_lcd.Draw_Rectangle( 171 30, 140, 450, 141); 172 my_lcd.Print_String("Oil Pressure", 270, 15); 173 174 my_lcd.Draw_Rectangle( 430, 10, 460, 30); 175 176 my_lcd.Print_String("Normal 177 Speed", 270, 40); 178 my_lcd.Draw_Rectangle( 430, 35, 460, 55); 179 180 my_lcd.Print_String("Over 181 Speed", 290, 65); 182 my_lcd.Draw_Rectangle( 430, 60, 460, 80); 183 184 my_lcd.Print_String("Centrifuge", 185 290, 90); 186 my_lcd.Draw_Rectangle( 430, 85, 460, 105); 187 188 my_lcd.Print_String("Pump:", 189 280, 115); 190 my_lcd.Draw_Rectangle( 430, 110, 460, 130); 191 192 my_lcd.Print_String("Telemetry", 193 10, 150); 194 my_lcd.Draw_Rectangle( 10, 170, 260, 300); 195 // 196 // Add 197 Startup Initalising text 198 //DisplayMessage(""); 199 // 200 // Temp 0 to 201 900 deg 202 my_lcd.Draw_Circle(365,230,18); 203 my_lcd.Draw_Circle(365,230,50); 204 205 my_lcd.Draw_Circle(365,230,70); 206 // 207 my_lcd.Set_Text_Size(1); 208 my_lcd.Print_String("0", 209 280, 250); 210 my_lcd.Print_String("200", 370, 150); 211 my_lcd.Print_String("650", 212 440, 210); 213 my_lcd.Print_String("830", 420, 280); 214 my_lcd.Print_String("1000", 215 345, 305); 216 my_lcd.Draw_Rectangle( 10, 170, 260, 300); 217 218 219 220 //my_lcd.Draw_Line(365,260,365,300); 221 // (x,y) = (12*sin(115), 12*cos(115)) 222 223 //my_lcd.Draw_Line(30*sin(Deg)+365,30*cos(Deg)+230,70*sin(Deg)+365,70*cos(Deg)+230); 224 225 226 my_lcd.Set_Draw_color(RED); 227 228 for (float T = 0; T<300; T+=1) 229 { 230 231 //my_lcd.Draw_Line((30*sin(T*Rad ))+365,(30*cos(T*Rad))+230,(70*sin(T*Rad))+365,(70*cos(T*Rad))+230); 232 233 my_lcd.Draw_Line((50*sin(T*Rad ))+365,(50*cos(T*Rad))+230,(69*sin(T*Rad))+365,(69*cos(T*Rad))+230); 234 235 236if ( T ==50)my_lcd.Set_Draw_color(GREEN); 237if ( T ==100)my_lcd.Set_Draw_color(BLUE); 238//if 239 ( T ==150)my_lcd.Set_Draw_color(RED); 240 241 //Serial.println((String) (T) +" 242 x:"+(String) ((30*sin(T*Rad))) + " y:"+ (String) ((30*cos(T*Rad))) + " :" + 243 (String) (sin(T*Rad)) ); 244 //(30*sin(T))+365,(30*cos(T))+230,(70*sin(T))+365,(70*cos(T))+230) 245 246 } 247 248my_lcd.Set_Draw_color(RED); 249my_lcd.Draw_Line((46*sin(50*Rad ))+365,(46*cos(50*Rad))+230,(49*sin(50*Rad))+365,(49*cos(50*Rad))+230); 250my_lcd.Draw_Line((46*sin(100*Rad 251 ))+365,(46*cos(100*Rad))+230,(49*sin(100*Rad))+365,(49*cos(100*Rad))+230); 252my_lcd.Draw_Line((46*sin(150*Rad 253 ))+365,(46*cos(150*Rad))+230,(49*sin(150*Rad))+365,(49*cos(150*Rad))+230); 254my_lcd.Draw_Line((46*sin(200*Rad 255 ))+365,(46*cos(200*Rad))+230,(49*sin(200*Rad))+365,(49*cos(200*Rad))+230); 256my_lcd.Draw_Line((46*sin(250*Rad 257 ))+365,(46*cos(250*Rad))+230,(49*sin(250*Rad))+365,(49*cos(250*Rad))+230); 258my_lcd.Draw_Line((46*sin(300*Rad 259 ))+365,(46*cos(300*Rad))+230,(49*sin(300*Rad))+365,(49*cos(300*Rad))+230); 260 261//uint16_t 262 x,y; 263//x=10; 264//y=100; 265// 266// for (int16_t row = 0; row < 200; row++) 267 268// { 269// my_lcd.Read_GRAM(x, y + row, buf,wid, 1); 270// my_lcd.Set_Addr_Window(x, 271 y + row, x + wid - 1, y + row); 272// my_lcd.Push_Any_Color(buf + dx, 273 wid - dx, 1,0); 274// my_lcd.Push_Any_Color(buf + 0, dx, 0,0); 275// 276 } 277 278// 279// 280 timer.every(1000, DisplayTime); 281 // 282 // Display 283 layout Initalised, allow messages 284 DisplayReady=true; 285 286 // 287 // Move 288 Temperature Display 289 for (float T = 1000; T>=0; T-=8) 290 {DisplayTemperature(T);} 291 292 //DisplayTemperature(0); 293 294// my_lcd.Set_Text_colour(WHITE); 295// TempPointer=0; 296// 297 my_lcd.Set_Draw_color(WHITE); 298// my_lcd.Draw_Line((20*sin(300*Rad ))+365,(20*cos(300*Rad))+230,(45*sin(300*Rad))+365,(45*cos(300*Rad))+230); 299// 300 my_lcd.Draw_Line((20*sin(299*Rad ))+365,(20*cos(299*Rad))+230,(45*sin(299*Rad))+365,(45*cos(299*Rad))+230); 301 302 303 304 //my_lcd.Fill_Triangle(50,50,75,25,100,50); 305 //my_lcd.Draw_Triangle 306// 307 my_lcd.Fill_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 308// 309 my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 310// 311 my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 312 313 314 315 316 317 //my_lcd.Set_Text_colour(WHITE); 318 // 319 // 320 //RunTime 321 = millis(); // call before Start 322 323 324} 325 326 327// 328// the loop function 329 runs over and over again forever 330// ======================================================================== 331void 332 loop() { 333 334// abc='Oil Pressure'; 335// my_lcd.Print_String(abc, 270, 15); 336 337 338 //if (SystemRun == true) { DisplayTime();} 339 340 // if (((millis()-c)/1000) 341 > l_time) 342 // {} 343 344timer.tick(); // tick the timer 345 346// if (millis()/1000 347 ==15) SetSensor(1,true); 348// if (millis()/1000 ==20) SetSensor(1,false); 349// 350// 351 if (millis()/1000 ==15) SetSensor(3,true); 352// if (millis()/1000 ==30) SetSensor(3,false); 353// 354 355// DisplayMessage((String) millis()); 356 357// Serial.println((String) 358 millis()); 359 360//uint16_t scrollbuf[my_lcd.Get_Display_Height()]; 361// 362// 363 for (int16_t i = my_lcd.Get_Display_Width(), dx = 4, dy = 0; i > 0; i -= dx) 364// 365 { 366// windowScroll(0, 216, my_lcd.Get_Display_Width(), 16, 367 dx, dy, scrollbuf); 368// } 369 370 371} 372 373 374//// 375//// function 376 that executes whenever data is requested by master 377//// this function is registered 378 as an event, see setup() 379//void requestEvent() { 380// 381// 382// 383// 384 Wire.write("Mooo- "); // respond with message of 6 bytes 385// // as expected 386 by master 387// 388// 389//} 390 391// function that executes whenever data is 392 received from master 393// this function is registered as an event, see setup() 394void 395 receiveEvent(int howMany) 396{ 397 // 398 // protocol 399 // Start 1,"buff",0 400 401 // Stop 2,"",0 402 // Reset 3,"",0 403 // Message 4,"String,0/1 404 405 // Sensor 5,"T/F",x 406 // Temp 6,"",X 407 // Speed 7,"",X 408 409 410 String InBuff=""; 411 // 412 // Get command Identifier 00 to 15 413 int 414 Command = Wire.read(); 415 if (Command >0 and Command<20) { 416 417 while(2 418 < Wire.available()) // loop through all but the last 3 419 { 420 char 421 c = Wire.read(); // receive byte as a character 422 InBuff+=c; 423 //if 424 (c==","){InBuff="";} 425 //else if() {In+=c} 426 //Command+=c; // 427 build command 428 //Serial.print(c); // print the character 429 } 430 431 // 432 //Wire.read(); // read string terminator 433 //Wire.read(); 434 // read a seperator 435 //int InVal1 = Wire.read(); // read 436 string terminator 437 //int InVal2 = Wire.read(); // read a seperator 438 439 int InVal2 = Wire.read(); // read last char 440 int InVal3 = Wire.read(); 441 // read last char 442 443 int InVal= (InVal3 << 8)+InVal2; 444 // 445 446 // if this worked i should have all parts 447 //Serial.println("Incomming 448 bytes:" + (String) howMany); 449 // 450 // if display is not read skip the 451 incomming update 452 if (DisplayReady==true) 453 { 454 //if (Dev==true) 455 {Serial.println("Command:" + (String) Command +" Val:"+(String)InVal);}; 456 457 //if (Dev==true) {Serial.println("Command:" + (String) Command +" Val:"+(String)InVal2+" 458 Val:"+(String)InVal3);}; 459 switch (Command) { 460 case 1: // Start 461 timer 462 //RunTime=0; 463 RunTime=millis(); 464 SystemRun=true; 465 466 break; 467 468 case 2: // Stop timer 469 //RunTime=0; 470 471 SystemRun=false; 472 break; 473 474 case 475 3: // Reset all info 476 RunTime=0; // Resets Clock on Display 477 478 SystemRun=true; // forces clock update to 00:00 479 480 DisplayTemperature(0); // Reset Temperature until next update 481 DisplayClear(); 482 // 483 UpdateSensor(0,false); // Oil Pressure 484 UpdateSensor(1,false); 485 // Normal Speed 486 UpdateSensor(2,false); // Over Speed 487 UpdateSensor(3,true); 488 // Centrifuge 489 UpdateSensor(4,false); // Boost Pump 490 491 break; 492 493 case 4: // Display Message 494 if 495 (InBuff.length() >=4 and InBuff.length() <=20) 496 DisplayMessage(InBuff); 497 498 break; 499 500 // case 5: //DisplayMessage(InBuff); 501 502 // if (InBuff=="true") 503 // {UpdateSensor(InVal,true);} 504 505 // else 506 // {UpdateSensor(InVal,false);} 507 // 508 break; 509 510 case 6: // Temperature 511 DisplayTemperature(InVal); 512 513 break; 514 515 case 7: // Speed Not Used Yet 516 517 DisplaySpeed(InVal); 518 break; 519 520 // 521 case 8: 522 // case 9: 523 524 case 10: // Sensor 0 Overspeed 525 526 if (InVal==0) 527 {UpdateSensor(0,true);} 528 else 529 530 {UpdateSensor(0,false);} 531 break; 532 case 11: // 533 Sensor 1 Norm RPM 534 if (InVal==0) 535 {UpdateSensor(1,true);} 536 537 else 538 {UpdateSensor(1,false);} 539 break; 540 case 541 12: // Sensor 2 Oil 542 if (InVal==0) 543 {UpdateSensor(2,true);} 544 545 else 546 {UpdateSensor(2,false);} 547 break; 548 case 549 13: // Sensor 3 centrifuge 550 if (InVal==0) 551 {UpdateSensor(3,true);} 552 553 else 554 {UpdateSensor(3,false);} 555 break; 556 case 557 14: // Sensor 4 pump 558 if (InVal==0) 559 {UpdateSensor(4,true);} 560 561 else 562 {UpdateSensor(4,false);} 563 break; 564 565 566 567 default: 568 // Nothing to do 569 break; 570 571 } 572 } 573 } 574} 575// 576// Right hand Pressure sensors 577void UpdateSensor(int 578 SwitchNo,bool Sensor) 579{ 580 if (Sensor== true) 581 {my_lcd.Fill_Rect( 582 432,(SwitchNo*25)+12,27,17, RED );} 583 else 584 {my_lcd.Fill_Rect( 432,(SwitchNo*25)+12,27,17, 585 BLACK );} 586} 587// 588// Poss RPM Sensor display 589void DisplaySpeed(int NewSpeed) 590 591 { 592 // ToDo 593 } 594// 595// Temperature Pointer display 596void DisplayTemperature(int 597 NewTemp) 598{ 599 // 600 if (Dev==true) {Serial.println("Temp:" + (String)NewTemp);}; 601 602 //Temp Range 0-1000 603 NewTemp=((NewTemp/3.33)-300)*-1; 604 if (DisplayReady==true) 605 606 { 607 // 608 DisplayReady=false; 609 // 610 611 // 612 613 if (TempPointer != NewTemp) { 614 // Clear Old 615 my_lcd.Set_Draw_color(BLACK); 616 617 my_lcd.Draw_Line((20*sin(TempPointer*Rad ))+365,(20*cos(TempPointer*Rad))+230,(45*sin(TempPointer*Rad))+365,(45*cos(TempPointer*Rad))+230); 618 619 my_lcd.Draw_Line((20*sin((TempPointer-1)*Rad ))+365,(20*cos((TempPointer-1)*Rad))+230,(45*sin((TempPointer-1)*Rad))+365,(45*cos((TempPointer-1)*Rad))+230); 620 621 622 //my_lcd.Fill_Triangle(0, y0, x1, y1, x2, y2) 623 // Show 624 New 625 my_lcd.Set_Draw_color(WHITE); 626 my_lcd.Draw_Line((20*sin(NewTemp*Rad 627 ))+365,(20*cos(NewTemp*Rad))+230,(45*sin(NewTemp*Rad))+365,(45*cos(NewTemp*Rad))+230); 628 629 my_lcd.Draw_Line((20*sin((NewTemp-1)*Rad ))+365,(20*cos((NewTemp-1)*Rad))+230,(45*sin((NewTemp-1)*Rad))+365,(45*cos((NewTemp-1)*Rad))+230); 630 631 // Save Current Pointer 632 TempPointer=NewTemp; 633 } 634 // 635 636 DisplayReady=true; 637 } 638} 639 640void DisplayClear() 641{ // should we 642 wait for DisplayReady ?? 643 644 //Line1="";Line2="";Line3=""; 645 //my_lcd.Set_Text_colour(BLACK); 646 647 //my_lcd.Draw_Rectangle( 10, 170, 260, 300); 648 //my_lcd.Fill_Rect( 10,170,260,300, 649 BLACK ); 650 DisplayMessage(""); 651 DisplayMessage(""); 652 DisplayMessage(""); 653 654 DisplayMessage("Reset"); 655 } 656 657void DisplayMessage(String Message) 658{ 659 660 if (DisplayReady==true) 661 { 662 // 663 DisplayReady=false; 664 665 666 my_lcd.Set_Text_Size(2); 667 668 my_lcd.Set_Text_colour(BLACK); 669 670 my_lcd.Print_String(Line1, 15, 192); 671 my_lcd.Set_Text_colour(WHITE); 672 673 my_lcd.Print_String(Line2, 15, 192); 674 675 my_lcd.Set_Text_colour(BLACK); 676 677 my_lcd.Print_String(Line2, 15, 212); 678 my_lcd.Set_Text_colour(WHITE); 679 680 my_lcd.Print_String(Line3, 15, 212); 681 682 my_lcd.Set_Text_colour(BLACK); 683 684 my_lcd.Print_String(Line3, 15, 232); 685 my_lcd.Set_Text_colour(WHITE); 686 687 my_lcd.Print_String(Line4, 15, 232); 688 689 my_lcd.Set_Text_colour(BLACK); 690 691 my_lcd.Print_String(Line4, 15, 252); 692 my_lcd.Set_Text_colour(WHITE); 693 694 my_lcd.Print_String(Message, 15, 252); 695 // 696 // my_lcd.Set_Text_colour(BLACK); 697 698 // my_lcd.Print_String(Line5, 15, 282); 699 // my_lcd.Set_Text_colour(WHITE); 700 701 // my_lcd.Print_String(Message,15, 282); 702 703 Line1=Line2; 704 705 Line2=Line3; 706 Line3=Line4; 707 Line4=Message;//Line5; 708 //Line5=Message; 709 710 if (Dev==true) {Serial.println(Message);}; 711 712 DisplayReady=true; 713 714 } 715} 716 717void DisplayTime() 718 { 719 int TxtColour = 0xE000; 720 String 721 Out =""; 722 723 if (SystemRun==true) //or (SystemRun==false and RunTime>0)) 724 725 //if (DisplayReady==true) 726 { 727 // 728 //DisplayReady=false; 729 // 730 731 if (RunTime ==0) 732 { 733 Out ="00:00"; 734 //my_lcd.Set_Text_colour(0xE000); 735 736 SystemRun=false; 737 } 738 739 else 740 { 741 742 Out=""; 743 Ts=((millis()-RunTime)/1000); 744 Tm=(Ts/60); 745 746 Tm= Tm-((Tm/60)*60); 747 748 if (Tm>=60) Tm=0; 749 750 if (Tm<10) Out ="0"; 751 Out+=(String)Tm +":"; 752 753 754 Ts= Ts-((Ts/60)*60); 755 if (Ts<10) Out +="0"; 756 757 Out+=(String)Ts; 758 TxtColour =WHITE; 759 } 760 761 // 762 my_lcd.Set_Text_colour(TxtColour); 763 my_lcd.Set_Text_Size(5); 764 765 my_lcd.Print_String(Out , 30, 55); 766 //if (Dev==true) 767 {Serial.println("time :" + Out);}; 768 } 769 // 770 } 771// 772// 773//void 774 windowScroll(int16_t x, int16_t y, int16_t wid, int16_t ht, int16_t dx, int16_t 775 dy, uint16_t *buf) 776//{ 777// if (dx) 778// { 779// for (int16_t row 780 = 0; row < ht; row++) 781// { 782// my_lcd.Read_GRAM(x, y + row, 783 buf,wid, 1); 784// my_lcd.Set_Addr_Window(x, y + row, x + wid - 1, y 785 + row); 786// my_lcd.Push_Any_Color(buf + dx, wid - dx, 1,0); 787// my_lcd.Push_Any_Color(buf 788 + 0, dx, 0,0); 789// } 790// } 791// if (dy) 792// { 793// for 794 (int16_t col = 0; col < wid; col++) 795// { 796// my_lcd.Read_GRAM(x 797 + col, y, buf,1, ht); 798// my_lcd.Set_Addr_Window(x + col, y, x + col, 799 y + ht - 1); 800// my_lcd.Push_Any_Color(buf + dy, ht - dy, 1,0); 801// 802 my_lcd.Push_Any_Color(buf + 0, dy, 0,0); 803// } 804// } 805//} 806// 807// 808//draw 809 some filled triangles 810 void fill_triangles_test(void) 811{ 812 int y0 = 0; 813 814 int y2 = 0; 815 816 817 int i = 0; 818 my_lcd.Fill_Screen(BLACK); 819 for(i=my_lcd.Get_Display_Width()/2-1;i>0;i-=5) 820 821 { 822 823 my_lcd.Set_Draw_color(0,i+64,i+64); 824 my_lcd.Fill_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 825 826 my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 827 828 my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 829 830 my_lcd.Set_Draw_color(i,0,i); 831 my_lcd.Draw_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 832 833 my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 834 835 my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 836 837 } 838} 839
Display Controler
arduino
This created the main display UI, has a small update window to show messages, Run timer and Relay status And before im flooded with "why not do it this way" etc, its because i did and i do it for pleasure.
1/* 2 AI-9 APU Gas Turbine Display 3 ===================================================================== 4 5 Created 22/08/2021 6 by Derek Beacroft 7 8Display on I2C Line 9 CommandNo,"buff",Val 10 1,"",0 // Start 11 2,"",0 // Stop 12 3,"",0 // Reset Display 13 4,"message",0 // Display new message 14 5, 15 6,xxx // Temperature 16 7,xxx // Speed 17 8, 18 9, 19 10,"",01 // Over Speed 20 11,"",01 // Normal Speed 21 12,"",01 // Oil Pressure 22 13,"",01 // Centrifuge 23 14,"",01 // Boost Pump 24 25 free 399 26 27*/ 28#include <Wire.h> 29// 30// 31#include <LCDWIKI_GUI.h> //Core graphics library 32#include <LCDWIKI_SPI.h> //Hardware-specific library 33//paramters define 34#define MODEL ILI9488_18 35// 36#include <arduino-timer.h> 37//auto timer = timer_create_default(); // create a timer with default settings 38 39 40//https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html 41 42 43 44 45//#define CS A2 46//#define CD A3 47//#define RST A1 48//#define LED A0 //if you don't need to control the LED pin,you should set it to -1 and set it to 3.3V 49 50#define CS A2 51#define CD A0 52#define RST A1 53#define LED A3 //if you don't need to control the LED pin,you should set it to -1 and set it to 3.3V 54 55#define Rad (float) 0.01745329 56 57unsigned long RunTime = 0; 58bool SystemRun = false; 59bool Dev = false; 60 61//the definiens of hardware spi mode as follow: 62//if the IC model is known or the modules is unreadable,you can use this constructed function 63LCDWIKI_SPI my_lcd(MODEL,CS,CD,RST,LED); //model,cs,dc,reset,led 64 65//define some colour values 66#define BLACK 0x0000 67#define BLUE 0x001F 68#define RED 0xF800 69#define GREEN 0x07E0 70#define CYAN 0x07FF 71#define MAGENTA 0xF81F 72#define YELLOW 0xFFE0 73#define WHITE 0xFFFF 74 75//#define Op (String) "Oil Pressure:" 76//#define Space (String) " " 77 78int Tm; 79int Ts; 80int TempPointer = 300; // Initial point of Temp gauge 81//bool Ready = false; // Display Initialised and Ready 82bool DisplayReady = false; // Display Initialised and Ready 83 84String Line1=""; 85String Line2="";//"Initialising"; 86//String Line3="AI-9 Control v1.0"; 87String Line3=""; 88String Line4=""; 89//String Line5=""; 90//char abc(20); 91 92 93 94 95 96void setup() { 97 // 98 //pinMode(LED, OUTPUT); // TFT Backlite 99 //analogWrite(LED, 250); // Power level (Max 3v) 100 Serial.begin(115200); // start serial for output 101 102 // 103 Wire.begin(8); // join i2c bus with address #8 104 //Wire.onRequest(requestEvent); // register outgoung event 105 Wire.onReceive(receiveEvent); // register incommong event 106 107 my_lcd.Init_LCD(); 108 my_lcd.Fill_Screen(0x0); 109 //Serial.println("Init"); 110 111my_lcd.Led_control(true); 112 // 113 // left,top,left+,right+ 114 //mylcd.Fill_Screen(BLACK); 115 my_lcd.Set_Rotation(1); 116 my_lcd.Set_Text_Back_colour(BLACK); 117 my_lcd.Set_Text_colour(0xE000); 118 119 //my_lcd.Print_String("Initialising AI-9", 10, 10); 120 my_lcd.Set_Text_Size(4); 121 my_lcd.Print_String("RUN TIME", 10, 10); 122 my_lcd.Set_Text_Size(5); 123 my_lcd.Print_String("00:00", 30, 55); 124 125 my_lcd.Set_Text_Size(2); 126 my_lcd.Draw_Rectangle( 0, 0, 477, 317); 127 my_lcd.Draw_Rectangle( 1, 1, 476, 316); 128 my_lcd.Draw_Rectangle( 2, 2, 475, 315); 129 130 my_lcd.Draw_Rectangle( 30, 140, 450, 141); 131 my_lcd.Print_String("Oil Pressure", 270, 15); 132 my_lcd.Draw_Rectangle( 430, 10, 460, 30); 133 134 my_lcd.Print_String("Normal Speed", 270, 40); 135 my_lcd.Draw_Rectangle( 430, 35, 460, 55); 136 137 my_lcd.Print_String("Over Speed", 290, 65); 138 my_lcd.Draw_Rectangle( 430, 60, 460, 80); 139 140 my_lcd.Print_String("Centrifuge", 290, 90); 141 my_lcd.Draw_Rectangle( 430, 85, 460, 105); 142 143 my_lcd.Print_String("Pump:", 280, 115); 144 my_lcd.Draw_Rectangle( 430, 110, 460, 130); 145 146 my_lcd.Print_String("Telemetry", 10, 150); 147 my_lcd.Draw_Rectangle( 10, 170, 260, 300); 148 // 149 // Add Startup Initalising text 150 //DisplayMessage(""); 151 // 152 // Temp 0 to 900 deg 153 my_lcd.Draw_Circle(365,230,18); 154 my_lcd.Draw_Circle(365,230,50); 155 my_lcd.Draw_Circle(365,230,70); 156 // 157 my_lcd.Set_Text_Size(1); 158 my_lcd.Print_String("0", 280, 250); 159 my_lcd.Print_String("200", 370, 150); 160 my_lcd.Print_String("650", 440, 210); 161 my_lcd.Print_String("830", 420, 280); 162 my_lcd.Print_String("1000", 345, 305); 163 my_lcd.Draw_Rectangle( 10, 170, 260, 300); 164 165 166 //my_lcd.Draw_Line(365,260,365,300); 167 // (x,y) = (12*sin(115), 12*cos(115)) 168 //my_lcd.Draw_Line(30*sin(Deg)+365,30*cos(Deg)+230,70*sin(Deg)+365,70*cos(Deg)+230); 169 170 my_lcd.Set_Draw_color(RED); 171 172 for (float T = 0; T<300; T+=1) 173 { 174 //my_lcd.Draw_Line((30*sin(T*Rad ))+365,(30*cos(T*Rad))+230,(70*sin(T*Rad))+365,(70*cos(T*Rad))+230); 175 my_lcd.Draw_Line((50*sin(T*Rad ))+365,(50*cos(T*Rad))+230,(69*sin(T*Rad))+365,(69*cos(T*Rad))+230); 176 177if ( T ==50)my_lcd.Set_Draw_color(GREEN); 178if ( T ==100)my_lcd.Set_Draw_color(BLUE); 179//if ( T ==150)my_lcd.Set_Draw_color(RED); 180 181 //Serial.println((String) (T) +" x:"+(String) ((30*sin(T*Rad))) + " y:"+ (String) ((30*cos(T*Rad))) + " :" + (String) (sin(T*Rad)) ); 182 //(30*sin(T))+365,(30*cos(T))+230,(70*sin(T))+365,(70*cos(T))+230) 183 } 184 185my_lcd.Set_Draw_color(RED); 186my_lcd.Draw_Line((46*sin(50*Rad ))+365,(46*cos(50*Rad))+230,(49*sin(50*Rad))+365,(49*cos(50*Rad))+230); 187my_lcd.Draw_Line((46*sin(100*Rad ))+365,(46*cos(100*Rad))+230,(49*sin(100*Rad))+365,(49*cos(100*Rad))+230); 188my_lcd.Draw_Line((46*sin(150*Rad ))+365,(46*cos(150*Rad))+230,(49*sin(150*Rad))+365,(49*cos(150*Rad))+230); 189my_lcd.Draw_Line((46*sin(200*Rad ))+365,(46*cos(200*Rad))+230,(49*sin(200*Rad))+365,(49*cos(200*Rad))+230); 190my_lcd.Draw_Line((46*sin(250*Rad ))+365,(46*cos(250*Rad))+230,(49*sin(250*Rad))+365,(49*cos(250*Rad))+230); 191my_lcd.Draw_Line((46*sin(300*Rad ))+365,(46*cos(300*Rad))+230,(49*sin(300*Rad))+365,(49*cos(300*Rad))+230); 192 193//uint16_t x,y; 194//x=10; 195//y=100; 196// 197// for (int16_t row = 0; row < 200; row++) 198// { 199// my_lcd.Read_GRAM(x, y + row, buf,wid, 1); 200// my_lcd.Set_Addr_Window(x, y + row, x + wid - 1, y + row); 201// my_lcd.Push_Any_Color(buf + dx, wid - dx, 1,0); 202// my_lcd.Push_Any_Color(buf + 0, dx, 0,0); 203// } 204 205// 206// 207 timer.every(1000, DisplayTime); 208 // 209 // Display layout Initalised, allow messages 210 DisplayReady=true; 211 212 // 213 // Move Temperature Display 214 for (float T = 1000; T>=0; T-=8) 215 {DisplayTemperature(T);} 216 //DisplayTemperature(0); 217 218// my_lcd.Set_Text_colour(WHITE); 219// TempPointer=0; 220// my_lcd.Set_Draw_color(WHITE); 221// my_lcd.Draw_Line((20*sin(300*Rad ))+365,(20*cos(300*Rad))+230,(45*sin(300*Rad))+365,(45*cos(300*Rad))+230); 222// my_lcd.Draw_Line((20*sin(299*Rad ))+365,(20*cos(299*Rad))+230,(45*sin(299*Rad))+365,(45*cos(299*Rad))+230); 223 224 225 //my_lcd.Fill_Triangle(50,50,75,25,100,50); 226 //my_lcd.Draw_Triangle 227// my_lcd.Fill_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 228// my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 229// my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 230 231 232 233 234 //my_lcd.Set_Text_colour(WHITE); 235 // 236 // 237 //RunTime = millis(); // call before Start 238 239 240} 241 242 243// 244// the loop function runs over and over again forever 245// ======================================================================== 246void loop() { 247 248// abc='Oil Pressure'; 249// my_lcd.Print_String(abc, 270, 15); 250 251 //if (SystemRun == true) { DisplayTime();} 252 253 // if (((millis()-c)/1000) > l_time) 254 // {} 255 256timer.tick(); // tick the timer 257 258// if (millis()/1000 ==15) SetSensor(1,true); 259// if (millis()/1000 ==20) SetSensor(1,false); 260// 261// if (millis()/1000 ==15) SetSensor(3,true); 262// if (millis()/1000 ==30) SetSensor(3,false); 263// 264// DisplayMessage((String) millis()); 265 266// Serial.println((String) millis()); 267 268//uint16_t scrollbuf[my_lcd.Get_Display_Height()]; 269// 270// for (int16_t i = my_lcd.Get_Display_Width(), dx = 4, dy = 0; i > 0; i -= dx) 271// { 272// windowScroll(0, 216, my_lcd.Get_Display_Width(), 16, dx, dy, scrollbuf); 273// } 274 275 276} 277 278 279//// 280//// function that executes whenever data is requested by master 281//// this function is registered as an event, see setup() 282//void requestEvent() { 283// 284// 285// 286// Wire.write("Mooo- "); // respond with message of 6 bytes 287// // as expected by master 288// 289// 290//} 291 292// function that executes whenever data is received from master 293// this function is registered as an event, see setup() 294void receiveEvent(int howMany) 295{ 296 // 297 // protocol 298 // Start 1,"buff",0 299 // Stop 2,"",0 300 // Reset 3,"",0 301 // Message 4,"String,0/1 302 // Sensor 5,"T/F",x 303 // Temp 6,"",X 304 // Speed 7,"",X 305 306 String InBuff=""; 307 // 308 // Get command Identifier 00 to 15 309 int Command = Wire.read(); 310 if (Command >0 and Command<20) { 311 312 while(2 < Wire.available()) // loop through all but the last 3 313 { 314 char c = Wire.read(); // receive byte as a character 315 InBuff+=c; 316 //if (c==","){InBuff="";} 317 //else if() {In+=c} 318 //Command+=c; // build command 319 //Serial.print(c); // print the character 320 } 321 // 322 //Wire.read(); // read string terminator 323 //Wire.read(); // read a seperator 324 //int InVal1 = Wire.read(); // read string terminator 325 //int InVal2 = Wire.read(); // read a seperator 326 int InVal2 = Wire.read(); // read last char 327 int InVal3 = Wire.read(); // read last char 328 329 int InVal= (InVal3 << 8)+InVal2; 330 // 331 // if this worked i should have all parts 332 //Serial.println("Incomming bytes:" + (String) howMany); 333 // 334 // if display is not read skip the incomming update 335 if (DisplayReady==true) 336 { 337 //if (Dev==true) {Serial.println("Command:" + (String) Command +" Val:"+(String)InVal);}; 338 //if (Dev==true) {Serial.println("Command:" + (String) Command +" Val:"+(String)InVal2+" Val:"+(String)InVal3);}; 339 switch (Command) { 340 case 1: // Start timer 341 //RunTime=0; 342 RunTime=millis(); 343 SystemRun=true; 344 break; 345 346 case 2: // Stop timer 347 //RunTime=0; 348 SystemRun=false; 349 break; 350 351 case 3: // Reset all info 352 RunTime=0; // Resets Clock on Display 353 SystemRun=true; // forces clock update to 00:00 354 DisplayTemperature(0); // Reset Temperature until next update 355 DisplayClear(); // 356 UpdateSensor(0,false); // Oil Pressure 357 UpdateSensor(1,false); // Normal Speed 358 UpdateSensor(2,false); // Over Speed 359 UpdateSensor(3,true); // Centrifuge 360 UpdateSensor(4,false); // Boost Pump 361 break; 362 363 case 4: // Display Message 364 if (InBuff.length() >=4 and InBuff.length() <=20) 365 DisplayMessage(InBuff); 366 break; 367 368 // case 5: //DisplayMessage(InBuff); 369 // if (InBuff=="true") 370 // {UpdateSensor(InVal,true);} 371 // else 372 // {UpdateSensor(InVal,false);} 373 // break; 374 375 case 6: // Temperature 376 DisplayTemperature(InVal); 377 break; 378 379 case 7: // Speed Not Used Yet 380 DisplaySpeed(InVal); 381 break; 382 383 // case 8: 384 // case 9: 385 386 case 10: // Sensor 0 Overspeed 387 if (InVal==0) 388 {UpdateSensor(0,true);} 389 else 390 {UpdateSensor(0,false);} 391 break; 392 case 11: // Sensor 1 Norm RPM 393 if (InVal==0) 394 {UpdateSensor(1,true);} 395 else 396 {UpdateSensor(1,false);} 397 break; 398 case 12: // Sensor 2 Oil 399 if (InVal==0) 400 {UpdateSensor(2,true);} 401 else 402 {UpdateSensor(2,false);} 403 break; 404 case 13: // Sensor 3 centrifuge 405 if (InVal==0) 406 {UpdateSensor(3,true);} 407 else 408 {UpdateSensor(3,false);} 409 break; 410 case 14: // Sensor 4 pump 411 if (InVal==0) 412 {UpdateSensor(4,true);} 413 else 414 {UpdateSensor(4,false);} 415 break; 416 417 418 default: 419 // Nothing to do 420 break; 421 } 422 } 423 } 424} 425// 426// Right hand Pressure sensors 427void UpdateSensor(int SwitchNo,bool Sensor) 428{ 429 if (Sensor== true) 430 {my_lcd.Fill_Rect( 432,(SwitchNo*25)+12,27,17, RED );} 431 else 432 {my_lcd.Fill_Rect( 432,(SwitchNo*25)+12,27,17, BLACK );} 433} 434// 435// Poss RPM Sensor display 436void DisplaySpeed(int NewSpeed) 437 { 438 // ToDo 439 } 440// 441// Temperature Pointer display 442void DisplayTemperature(int NewTemp) 443{ 444 // 445 if (Dev==true) {Serial.println("Temp:" + (String)NewTemp);}; 446 //Temp Range 0-1000 447 NewTemp=((NewTemp/3.33)-300)*-1; 448 if (DisplayReady==true) 449 { 450 // 451 DisplayReady=false; 452 // 453 454 // 455 if (TempPointer != NewTemp) { 456 // Clear Old 457 my_lcd.Set_Draw_color(BLACK); 458 my_lcd.Draw_Line((20*sin(TempPointer*Rad ))+365,(20*cos(TempPointer*Rad))+230,(45*sin(TempPointer*Rad))+365,(45*cos(TempPointer*Rad))+230); 459 my_lcd.Draw_Line((20*sin((TempPointer-1)*Rad ))+365,(20*cos((TempPointer-1)*Rad))+230,(45*sin((TempPointer-1)*Rad))+365,(45*cos((TempPointer-1)*Rad))+230); 460 461 //my_lcd.Fill_Triangle(0, y0, x1, y1, x2, y2) 462 // Show New 463 my_lcd.Set_Draw_color(WHITE); 464 my_lcd.Draw_Line((20*sin(NewTemp*Rad ))+365,(20*cos(NewTemp*Rad))+230,(45*sin(NewTemp*Rad))+365,(45*cos(NewTemp*Rad))+230); 465 my_lcd.Draw_Line((20*sin((NewTemp-1)*Rad ))+365,(20*cos((NewTemp-1)*Rad))+230,(45*sin((NewTemp-1)*Rad))+365,(45*cos((NewTemp-1)*Rad))+230); 466 // Save Current Pointer 467 TempPointer=NewTemp; 468 } 469 // 470 DisplayReady=true; 471 } 472} 473 474void DisplayClear() 475{ // should we wait for DisplayReady ?? 476 477 //Line1="";Line2="";Line3=""; 478 //my_lcd.Set_Text_colour(BLACK); 479 //my_lcd.Draw_Rectangle( 10, 170, 260, 300); 480 //my_lcd.Fill_Rect( 10,170,260,300, BLACK ); 481 DisplayMessage(""); 482 DisplayMessage(""); 483 DisplayMessage(""); 484 DisplayMessage("Reset"); 485 } 486 487void DisplayMessage(String Message) 488{ 489 if (DisplayReady==true) 490 { 491 // 492 DisplayReady=false; 493 494 my_lcd.Set_Text_Size(2); 495 496 my_lcd.Set_Text_colour(BLACK); 497 my_lcd.Print_String(Line1, 15, 192); 498 my_lcd.Set_Text_colour(WHITE); 499 my_lcd.Print_String(Line2, 15, 192); 500 501 my_lcd.Set_Text_colour(BLACK); 502 my_lcd.Print_String(Line2, 15, 212); 503 my_lcd.Set_Text_colour(WHITE); 504 my_lcd.Print_String(Line3, 15, 212); 505 506 my_lcd.Set_Text_colour(BLACK); 507 my_lcd.Print_String(Line3, 15, 232); 508 my_lcd.Set_Text_colour(WHITE); 509 my_lcd.Print_String(Line4, 15, 232); 510 511 my_lcd.Set_Text_colour(BLACK); 512 my_lcd.Print_String(Line4, 15, 252); 513 my_lcd.Set_Text_colour(WHITE); 514 my_lcd.Print_String(Message, 15, 252); 515 // 516 // my_lcd.Set_Text_colour(BLACK); 517 // my_lcd.Print_String(Line5, 15, 282); 518 // my_lcd.Set_Text_colour(WHITE); 519 // my_lcd.Print_String(Message,15, 282); 520 521 Line1=Line2; 522 Line2=Line3; 523 Line3=Line4; 524 Line4=Message;//Line5; 525 //Line5=Message; 526 if (Dev==true) {Serial.println(Message);}; 527 528 DisplayReady=true; 529 } 530} 531 532void DisplayTime() 533 { 534 int TxtColour = 0xE000; 535 String Out =""; 536 537 if (SystemRun==true) //or (SystemRun==false and RunTime>0)) 538 //if (DisplayReady==true) 539 { 540 // 541 //DisplayReady=false; 542 // 543 if (RunTime ==0) 544 { 545 Out ="00:00"; 546 //my_lcd.Set_Text_colour(0xE000); 547 SystemRun=false; 548 } 549 550 else 551 { 552 Out=""; 553 Ts=((millis()-RunTime)/1000); 554 Tm=(Ts/60); 555 Tm= Tm-((Tm/60)*60); 556 557 if (Tm>=60) Tm=0; 558 if (Tm<10) Out ="0"; 559 Out+=(String)Tm +":"; 560 561 Ts= Ts-((Ts/60)*60); 562 if (Ts<10) Out +="0"; 563 Out+=(String)Ts; 564 TxtColour =WHITE; 565 } 566 // 567 my_lcd.Set_Text_colour(TxtColour); 568 my_lcd.Set_Text_Size(5); 569 my_lcd.Print_String(Out , 30, 55); 570 //if (Dev==true) {Serial.println("time :" + Out);}; 571 } 572 // 573 } 574// 575// 576//void windowScroll(int16_t x, int16_t y, int16_t wid, int16_t ht, int16_t dx, int16_t dy, uint16_t *buf) 577//{ 578// if (dx) 579// { 580// for (int16_t row = 0; row < ht; row++) 581// { 582// my_lcd.Read_GRAM(x, y + row, buf,wid, 1); 583// my_lcd.Set_Addr_Window(x, y + row, x + wid - 1, y + row); 584// my_lcd.Push_Any_Color(buf + dx, wid - dx, 1,0); 585// my_lcd.Push_Any_Color(buf + 0, dx, 0,0); 586// } 587// } 588// if (dy) 589// { 590// for (int16_t col = 0; col < wid; col++) 591// { 592// my_lcd.Read_GRAM(x + col, y, buf,1, ht); 593// my_lcd.Set_Addr_Window(x + col, y, x + col, y + ht - 1); 594// my_lcd.Push_Any_Color(buf + dy, ht - dy, 1,0); 595// my_lcd.Push_Any_Color(buf + 0, dy, 0,0); 596// } 597// } 598//} 599// 600// 601//draw some filled triangles 602 void fill_triangles_test(void) 603{ 604 int y0 = 0; 605 int y2 = 0; 606 607 608 int i = 0; 609 my_lcd.Fill_Screen(BLACK); 610 for(i=my_lcd.Get_Display_Width()/2-1;i>0;i-=5) 611 { 612 613 my_lcd.Set_Draw_color(0,i+64,i+64); 614 my_lcd.Fill_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 615 my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 616 my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 617 my_lcd.Set_Draw_color(i,0,i); 618 my_lcd.Draw_Triangle(my_lcd.Get_Display_Width()/2-1,my_lcd.Get_Display_Height()/2-1-i, 619 my_lcd.Get_Display_Width()/2-1-i,my_lcd.Get_Display_Height()/2-1+i, 620 my_lcd.Get_Display_Width()/2-1+i,my_lcd.Get_Display_Height()/2-1+i); 621 } 622} 623
Downloadable files
Nano to TFT
Direct connection of the Nano Every for the TFT, This uses an SPI connection to the TFT
Nano to TFT

Original Control System
This provides the timing and In/Out ports required
Original Control System

Nano to TFT
Direct connection of the Nano Every for the TFT, This uses an SPI connection to the TFT
Nano to TFT

Original Control System
This provides the timing and In/Out ports required
Original Control System

New Control system
Arduino control lines and wiring centre
New Control system

Documentation
Finger Plate
Cad layout of the Finger plate for routing
Finger Plate

TFT Display
Using the ILI9488.h library in an Arduino pretty much used up all the ram, so i used a nano every (bit more ram available) and connected it vai SPI, this gave me a graphics controller with its own GUI . you have to build the GUI but it was reasonably strait forward.
TFT Display

Mounting Board
Nothing special, 2mm galvanized plate, but it became a jigsaw to work out where it all goes
Mounting Board

Finger Plate
Cad layout of the Finger plate for routing
Finger Plate

Finger Plate
Make things look cool, I used a small CNC router to produce the finger plate with decals and cut outs.
Finger Plate

TFT Display
Using the ILI9488.h library in an Arduino pretty much used up all the ram, so i used a nano every (bit more ram available) and connected it vai SPI, this gave me a graphics controller with its own GUI . you have to build the GUI but it was reasonably strait forward.
TFT Display

Enclosure
I wanted a military look, in my head it looked bigger, on assembly i realy struggled to get it all in
Enclosure

AI-9 Russian Gas Turbine (APU)
Ok this is not off the shelf (certainly not any more) but necessary for the project
AI-9 Russian Gas Turbine (APU)

AI-9 Russian Gas Turbine (APU)
Ok this is not off the shelf (certainly not any more) but necessary for the project
AI-9 Russian Gas Turbine (APU)

Mounting Board
Nothing special, 2mm galvanized plate, but it became a jigsaw to work out where it all goes
Mounting Board

Finger Plate
Make things look cool, I used a small CNC router to produce the finger plate with decals and cut outs.
Finger Plate

Enclosure
I wanted a military look, in my head it looked bigger, on assembly i realy struggled to get it all in
file.None

Comments
Only logged in users can leave comments