Simulator Balap 2D DIY Menggunakan Arduino Nano & Servo SG90
Komponen dan Perlengkapan
Arduino Nano R3
×
1
Motor servo mikro SG90
×
2
Alat dan Mesin yang Diperlukan
Pemolakan (umum)
Aplikasi dan Layanan Online
Arduino IDE
Tentang Proyek Ini
SimTools adalah perangkat lunak Simulator Gerak generik yang mampu mengontrol berbagai antarmuka perangkat keras, termasuk Arduino. Kombinasi ini digunakan dalam proyek yang ditampilkan dalam video. Bagian perangkat keras hanya terdiri dari mikrokontroler Arduino Nano dan dua motor servo mikro SG90 murah. Kita hanya perlu mengunggah kode yang diberikan di bawah ini.
Data permainan yang diperlukan dengan bantuan perangkat lunak SimTools ditransmisikan melalui port serial ke Arduino. Selanjutnya Arduino mengaktifkan motor servo yang menggerakkan platform simulasi sesuai kebutuhan. Ini adalah skala kecil dari simulator dua sumbu. Untuk membuat simulator nyata, Anda perlu menambahkan pengemudi motor dan motor servo besar.
Ada banyak contoh simulator DIY seperti ini, serta gambar konstruksi dan tips di halaman "https://www.xsimulator.net/". Prosedur pengaturan SimTools dijelaskan dalam video, tetapi Anda juga dapat mengunduh manual pengguna PDF di: https://simtools.us/wp-content/uploads/2019/06/SimToolsUserManual-v2.4.pdf
SimTools akan berjalan dalam mode "Demo" hingga lisensi yang valid terdaftar. Plugin untuk Live for Speed beroperasi sepenuhnya untuk pengujian sementara SimTools dalam mode demo. (Demo Live for Speed juga akan berfungsi untuk pengujian SimTools.) Anda dapat menemukan informasi lebih lanjut dan mengunduh Live for Speed di https://www.lfs.net/downloads
//******************************************************************************************** // RC Model Servo // Original code By EAOROBBIE (Robert Lindsay) // Completely mangled by aarondc // For free use for Sim Tool Motion Software //******************************************************************************************** #include <Servo.h> //#define DEBUG 1 // comment out this line to remove debuggin Serial.print lines const int kActuatorCount = 2; // how many Actuators we are handling // the letters ("names") sent from Sim Tools to identify each actuator // NB: the order of the letters here determines the order of the remaining constants kPins and kActuatorScale const char kActuatorName[kActuatorCount] = { 'R', 'L' }; const int kPins[kActuatorCount] = {4, 5}; // pins to which the Actuators are attached const int kActuatorScale[kActuatorCount][2] = { { 0, 179 } , // Right Actuator scaling { 179, 0 } // Left side Actuator scaling }; const char kEOL = '~'; // End of Line - the delimiter for our acutator values const int kMaxCharCount = 3; // some insurance... Servo actuatorSet[kActuatorCount]; // our array of Actuators int actuatorPosition[kActuatorCount] = {90, 90}; // current Actuator positions, initialised to 90 int currentActuator; // keep track of the current Actuator being read in from serial port int valueCharCount = 0; // how many value characters have we read (must be less than kMaxCharCount!! // set up some states for our state machine // psReadActuator = next character from serial port tells us the Actuator // psReadValue = next 3 characters from serial port tells us the value enum TPortState { psReadActuator, psReadValue }; TPortState currentState = psReadActuator; void setup() { // attach the Actuators to the pins for (int i = 0; i < kActuatorCount; i++) actuatorSet[i].attach(kPins[i]); // initialise actuator position for (int i = 0; i < kActuatorCount; i++) updateActuator(i); Serial.begin(9600); // opens serial port at a baud rate of 9600 } void loop() { } // this code only runs when we have serial data available. ie (Serial.available() > 0). void serialEvent() { char tmpChar; int tmpValue; while (Serial.available()) { // if we're waiting for a Actuator name, grab it here if (currentState == psReadActuator) { tmpChar = Serial.read(); // look for our actuator in the array of actuator names we set up #ifdef DEBUG Serial.print("read in "); Serial.println(tmpChar); #endif for (int i = 0; i < kActuatorCount; i++) { if (tmpChar == kActuatorName[i]) { #ifdef DEBUG Serial.print("which is actuator "); Serial.println(i); #endif currentActuator = i; // remember which actuator we found currentState = psReadValue; // start looking for the Actuator position actuatorPosition[currentActuator] = 0; // initialise the new position valueCharCount = 0; // initialise number of value chars read in break; } } } // if we're ready to read in the current Actuator's position data if (currentState == psReadValue) { while ((valueCharCount < kMaxCharCount) && Serial.available()) { tmpValue = Serial.read(); if (tmpValue != kEOL) { tmpValue = tmpValue - 48; if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0; actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue; valueCharCount++; } else break; } // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name if (tmpValue == kEOL || valueCharCount == kMaxCharCount) { #ifdef DEBUG Serial.print("read in "); Serial.println(actuatorPosition[currentActuator]); #endif // scale the new position so the value is between 0 and 179 actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]); #ifdef DEBUG Serial.print("scaled to "); Serial.println(actuatorPosition[currentActuator]); #endif updateActuator(currentActuator); currentState = psReadActuator; } } } } // write the current Actuator position to the passed in Actuator void updateActuator(int thisActuator) { actuatorSet[thisActuator].write(actuatorPosition[thisActuator]); }