Membangun Stasiun Perintah DCC Digital untuk Rel Model Menggunakan Arduino – Aplikasi Gratis Tersertakan
Komponen dan Perlengkapan
SparkFun Arduino Pro Mini 328 - 5V/16MHz × 1
LMD18200t × 1
PCB × 1
Regulator Linier (7805) × 1
Dioda Zener 3.6V 0.5W × 1
Modul Bluetooth HC-06 × 1
Resistor 0.1 ohm 2 watt × 1
Kapasitor 220 µF 16 volt × 1
Kapasitor 10 µF 16 volt × 1
Kapasitor Cakram Keramik, 0.1 µF × 3
Resistor 10k ohm × 2
Resistor Lubang Lewat, 4.7 kohm × 1
Terminal bor 2 posisi 3.5 mm jarak pusat, 1.1 mm diameter pin × 1
Terminal bor 6 posisi 2.54 mm jarak pusat × 1
Soket 4 pin 2.54 mm × 1
Soket 12 pin 2.54 mm × 2
Aplikasi dan Layanan Online
LocoMotive (versi gratis)
LocoMotive DCC (versi terbaru termasuk baca/tulis CV 1 hingga 255)
Tentang Proyek
Apa yang berbeda tentang sistem ini ? Sirkuit elektronik yang sangat sederhana menyediakan sinyal DCC dan daya untuk rel, namun Aplikasi yang melakukan pekerjaan nyata !Komputer di ponsel Anda digunakan sepenuhnya dengan membangun kode yang diperlukan untuk membentuk setiap paket instruksi, sehingga menyederhanakan pekerjaan pengontrol Arduino !
Update 16 Agustus 2019: Rilis Aplikasi yang ditingkatkan baru - dengan fasilitas Baca / Tulis CV 1 hingga 255 Versi Aplikasi iniberbiaya £5 plus pajak dan tersedia di Google Play Store.
Update 18 Mei 2019: Rilis Aplikasi yang ditingkatkan baru - hingga 28 fungsi dengan judul yang dapat diedit, visibilitas dan opsi momentary. Kontrol hingga 4 lokomotif sekaligus dengan bar kecepatan di layar. Versi Aplikasi iniberbiaya £3 plus pajak dan tersedia di Google Play Store.
Update 17 Februari 2019: Anda mungkin perlu memodifikasi modul Bluetooth HC-06 untuk memperluas jangkauan penerimaannya.Saya menambahkan kawat tembagu padat (dari kabel tanah listrik) panjang 31,2 mm (1/4 panjang gelombang untuk 2,4 GHz). Lihat foto yang dilampirkan di Langkah 2.
Update 29 Januari 2019: Penambahan opsi momentary pada F2 dan F3 untuk suara klakson Tentukan kecepatan maks untuk setiap lokomotifIni adalah stasiun perintah DCC paling efisien yang dapat dibangun. Sistem lain tidak dapat melakukan begitu banyak dengan begitu sedikit komponen.Stasiun perintah DCC yang berfungsi sepenuhnya dan mudah dirangka dengan PCB yang tersedia di eBay serta hanya memerlukan beberapa bagian.Aplikasi 'LocoMotive' dirancang untuk beroperasi pada ponsel Android yang menjalankan versi 4.1 dan ke atas.Tidak perlu membeli sistem proprietari apa pun, ini adalah unit mandiri yang dioperasikan oleh aplikasi gratis bernama 'LocoMotive'Bekerja dengan decoder yang mematuhi NMRA. Sistem ini mengkompilasi paket operasi DCC dalam Aplikasi yang dikirim ke antarmuka Arduino untuk digabungkan dengan sinyal jam DCC. Beli PCB ini di eBay.Dapatkan aplikasi gratis LocoMotive di Google Play Store.Fitur-fitur meliputi:
Kontrol 1 hingga 20 lokomotif
Ideal untuk tata letak kecil hingga menengah
Beban 2 Ampere mengemudikan hingga 16 lokomotif OO/HO menggunakan H-bridge yang ditentukan
Tambah H-bridge yang kompatibel dengan arus lebih tinggi untuk memperluas kapasitas beban
Terlindung dari kortslit
Putus otomatis arus berlebih, dapat disesuaikan dalam kode Arduino
Lampu dan arah
Fungsi 1 hingga 8
Edit nama fungsi, visibilitas dan aksi momentary
Turnout / titik / aksesori mengoperasikan hingga 8 pasang output
Edit nama turnout
Penamaan kustom lokomotif Anda dan tetapkan kecepatan maks untuk masing-masing
Pemrograman alamat lokomotif CV1
Baca / tulis CV 1 hingga 255
Tambahkan alamat aksesori Anda sendiri
Pilih sumber daya DC yang sesuai dengan skala yang digunakan (Z/N/OO/HO/O/G) 12v hingga 20v
Selanjutnya dari pekerjaan sebelumnya pada sistem DCC nirkabel, saya telah mengembangkan Stasiun Perintah Bluetooth yang terhubung ke receiver sirkuit berbasis Arduino dengan modul BT HC-06 dan driver Motor H-bridge LMD18200 yang memberikan 2 Ampere.
Biaya keseluruhan bagian sekitar £20 dengan bagian yang dibeli dari eBay.
Langkah 1: Sketsa Arduino
Sketsa lengkap dilampirkan. Bagian ini adalah loop dan kode penerima data. Aplikasi Android mengirim paket lengkap ke penerima dan didekode di sini menjadi array data. Tergantung apakah 3 atau 4 byte diterima kode akan menghasilkan format paket DCC yang benar untuk rel kereta.
String teks yang diterima 'DD, 1, 129, 128, ' diterjemahkan menjadi paket Fungsi 3 byte 8 bit masing-masing :Decimal: [1] [129] [128] Binary: [0000 0001] [1000 0001] [1000 0000] Action: [Lokomotif 1] [ F1 on] [XOR data check]
Untuk informasi lebih lanjut tentang standar paket NMRA lihat:https://www.nmra.org/sites/default/files/s-9.2.1_2...
s-9.2.1_2012_07.pdf
LMD memerlukan sinyal DCC pada pin DIR dan pin PWM dipegang HIGH.
command_station_bluetooth_oct_2018.ino
Langkah 2: Diagram Sirkuit Fritzing
Arduino Pro Mini menerima data Bluetooth melalui modul HC-06. Arduino menghasilkan siklus jam standar NMRA dari data dalam format paket. Data yang diterima mengganggu urutan ketika data baru diterima dan paket DCC diperbarui untuk mengirim instruksi ke rel kereta.
Daftar bagian yang diperlukan:
PCB tersedia di eBay.
1 off Arduino Pro Mini Atmega328P 5V/16M eBay
1 off LMD18200T H-bridge eBay
1 off HC-06 Bluetooth module eBay
1 off 0.1 ohm 2W Metal Film Resistor 0.1R 2 Watt (11.5 mm x 4.5 mm) eBay
3 off Capacitor 0.1uf eBay
2 off 10kΩ Resistor eBay
1 off Capacitor 10uf 25v; eBay
1 off Capacitor 220uf 16v; eBay
1 off Phoenix Contact MKDS 1/ 2-3, 5 2 Way Screw PCB Terminal Block 13.5A 200V 3.5mm eBay
Sumber daya: Untuk tata letak OO/HO gunakan sumber daya DC 14v (mis. unit adapter charger laptop dari eBay). Misalnya ini memberikan hingga 2,5 Ampere. Periksa ukuran soket panel yang diperlukan untuk memasang soket DC pada sumber daya yang dipilih untuk proyek ini. https://www.ebay.co.uk/itm/Samsung-AC-DC-Adapter-...
Untuk memperluas jangkauan modul Bt HC-06, solder kawat di ujung antena pada modul. Saya menggunakan kawat tembagu padat (dari kabel tanah listrik) panjang 31,2 mm (1/4 panjang gelombang untuk 2,4 GHz). Lihat foto di atas.Mohon perhatikan - koneksi HC-06 adalah Rx (pada PCB) ke Rx (pada modul) dan Tx ke Tx. Mohon perhatikan, kawat antena harus dilapisi pelindung untuk menghindari kortslit secara tidak sengaja dengan komponen lain.
Untuk penggunaan modul h-bridge LMD18200 (seperti yang ditampilkan di atas ini dalam bentuk modul dengan heatsink dll), saya telah menambahkan komponen sens arus untuk memberikan proteksi dari masalah kortslit atau beban berlebih pada rel kereta, Diagram sirkuit yang diperbarui dan kode Arduino sekarang termasuk fungsi sens arus.
Kode membatasi arus maksimal ke 2 Ampere saat tercapai, h-bridge LMD18200 dimatikan dengan menerapkan sinyal HIGH dari D13 pada Arduino ke input 'Brake' pada h-bridge.
Penggunaan resistor sens arus 0.1 ohm memberikan rentang input analog 0 hingga 200 mv pada pin sensor Arduino A0 untuk beban hingga 2 Ampere. Untuk sekitar 5mv per langkah input analog (1023 total langkah atau pembagian) memberikan 0 hingga 40 pembagian atau 2 Ampere / 40 = 50mA per pembagian. Ketepatan pengukuran arus adalah 50 mA namun kita melindungi h-bridge saat 2 Ampere tercapai. LMD18200 juga memiliki proteksi suhu berlebih bawaan sebagai cadangan.if(C >2000){ // 2 amps
Nilai arus yang ditarik dikirim ke Aplikasi Android melalui Bluetooth setiap detik.void send_c(){t = millis() - lastmillis; if (t >= interval){ bluetooth.write(sensorValue); bluetooth.write('c'); lastmillis = millis(); } }
Langkah 3: Aplikasi Android
Unduh aplikasi gratis dari Google Play Store - 'LocoMotive'
Unduh aplikasi penuh (£5.99) dari Google Play Store - 'LocoMotive DCC'
Instruksi dilampirkan untuk versi penuh Aplikasi.
Kode
locomotive_dcc_sep19.ino
locomotive_dcc_sep19.inoArduino
Kode Arduino
// 1 Sep 2019 // sketch for use with Android App 'Locomotive DCC'using LMD18200 h-bridge // CV read/write facility added #include <SoftwareSerial.h> SoftwareSerial bluetooth(8,9); // RX TX int C; int sensorValue; long t = 0; long lastmillis = 0; long interval = 1000; String inString; int a[8]; int preamable_type = 0; int Address; float CV_VAL; float cv_val; float cv_val0; float cv_val1; float cv_val2; float cv_val3; float cv_val4; float cv_val5; float cv_val6; float cv_val7; int test_num; int cv_write_val; int Cs; boolean cv_logic; boolean ok; int num; // use digital pins 6 and 5 for DCC out //Timer frequency is 2MHz for ( /8 prescale from 16MHz ) #define TIMER_SHORT 0x8D // 58usec pulse length #define TIMER_LONG 0x1B // 116usec pulse length unsigned char last_timer=TIMER_SHORT; // store last timer value unsigned char flag=0; // used for short or long pulse unsigned char every_second_isr = 0; // pulse up or down // definitions for state machine #define PREAMBLE 0 #define SEPERATOR 1 #define SENDBYTE 2 unsigned char state= PREAMBLE; unsigned char preamble_count = 16; unsigned char outbyte = 0; unsigned char cbit = 0x80; // variables unsigned char xdata = 0, data = 0, data_f = 0,data_f1 = 0,data_f2 = 0; int locoAdr = 9; // this is the default address of the loco // buffer for command struct Message { unsigned char data[7]; unsigned char len; } ; #define MAXMSG 3 // for the time being, use only 2 messages - the idle msg, the loco Speed msg, function msg struct Message msg[MAXMSG] = { { { 0xFF,0, 0xFF, 0, 0, 0, 0}, 3}, // idle msg { { locoAdr, 0, 0, 0, 0, 0, 0}, 3} // locoMsg with 128 speed steps 0x3f }; // loco msg must be filled later with speed and XOR data byte int msgIndex=0; int byteIndex=0; //Setup Timer2. //Configures the 8-Bit Timer2 to generate an interrupt at the specified frequency. //Returns the time load value which must be loaded into TCNT2 inside your ISR routine. void SetupTimer2(){ //Timer2 Settings: Timer Prescaler /8, mode 0 //Timmer clock = 16MHz/8 = 2MHz oder 0,5usec TCCR2A = 0; TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; //Timer2 Overflow Interrupt Enable TIMSK2 = 1<<TOIE2; //load the timer for its first cycle TCNT2=TIMER_SHORT; } //Timer2 overflow interrupt vector handler ISR(TIMER2_OVF_vect) { //Capture the current timer value TCTN2. This is how much error we have //due to interrupt latency and the work in this function //Reload the timer and correct for latency. // for more info, see https://www.uchobby.com/index.php/2007/11/24/arduino-interrupts/ unsigned char latency; // for every second interupt just toggle signal if (every_second_isr) { PORTD = B01100000; //use this instead of digitalWrite(6,1); digitalWrite(5,1);for LMD18200 --- 5 to 'DIR' DCC signal and 6 to 'PWM' held HIGH //digitalWrite(6,1); digitalWrite(5,1); every_second_isr = 0; // set timer to last value latency=TCNT2; TCNT2=latency+last_timer; } else { // != every second interrupt, advance bit or state PORTD = B01000000; //for LMD18200 digitalWrite(6, 1); digitalWrite(5, 0) //digitalWrite(6, 1); digitalWrite(5, 0); every_second_isr = 1; switch(state) { case PREAMBLE: flag=1; // short pulse preamble_count--; if (preamble_count == 0) { // advance to next state state = SEPERATOR; // get next message msgIndex++; if (msgIndex >= MAXMSG) { msgIndex = 0; } byteIndex = 0; //start msg with byte 0 } break; case SEPERATOR: flag=0; // long pulse // then advance to next state state = SENDBYTE; // goto next byte ... cbit = 0x80; // send this bit next time first outbyte = msg[msgIndex].data[byteIndex]; break; case SENDBYTE: if (outbyte & cbit) { flag = 1; // send short pulse } else { flag = 0; // send long pulse } cbit = cbit >> 1; if (cbit == 0) { // last bit sent, is there a next byte? byteIndex++; if (byteIndex >= msg[msgIndex].len) { // this was already the XOR byte then advance to preamble state = PREAMBLE; if (preamable_type == 0){ preamble_count = 16; // normal preamble length of 16 '1's } if (preamable_type == 1){ preamble_count = 24; // preamble of 24 '1's for CV1 write } } else { // send separtor and advance to next byte state = SEPERATOR ; } } break; } if (flag) { // if data==1 then short pulse latency=TCNT2; TCNT2=latency+TIMER_SHORT; last_timer=TIMER_SHORT; } else { // long pulse latency=TCNT2; TCNT2=latency+TIMER_LONG; last_timer=TIMER_LONG; } } } void setup(){ Serial.begin(115200); analogReference(INTERNAL); pinMode(13, OUTPUT); bluetooth.begin(9600); delay(500); // wait for bluetooth module to start Serial.println("Bluetooth Started"); bluetooth.println("Bluetooth Started"); DDRD = B01100000; // register D5 for digital pin 5, D6 for digital pin 6 //Start the timer SetupTimer2(); t = millis(); lastmillis = millis(); digitalWrite(6, LOW); digitalWrite(13, HIGH); // turn bridge o/p off int get_cv_val = cv_calc(test_num); } void current(){ int i; int value = 0; int numReadings = 5; for (i = 0; i < numReadings; i++){ // Read sensor data. value = value + analogRead(A0); // 1ms pause adds more stability between reads. delay(1); } sensorValue = value/numReadings; // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 1.1V) = 1.08mv per division // 0.1 ohm resistor on current sense gives 200mv at 2 Amps or, 100mv per Amp // 1.08 mv per div for Internal Ref of 1.1v : 100/1.08 = 92.6 divisions per 1000mA or 1 div = 10.8mA C = 10.8 * sensorValue ; // mA if(C >2000){ // 2 amps Serial.println("Over Current"); bluetooth.println("Short!"); digitalWrite(6, LOW); // logic control of DCC signal to low (off) digitalWrite(13, HIGH); // to brake, shorts out h-bridge o/p bluetooth.println(C); } } void loop() { if(bluetooth.available() == true); { inString = bluetooth.readStringUntil('\n'); Serial.println(inString); } if (inString.substring(0,1) == "D"){ string(); } // incoming DCC packet if (inString.substring(0,1) == "C"){ digitalWrite(6, HIGH); digitalWrite(13, LOW); } // reset after over current, logic control of DCC signal on,brake off if (inString.substring(0,1) == "G"){ digitalWrite(6, HIGH); digitalWrite(13, LOW); current(); bluetooth.println(C);} // request for load current value if (inString.substring(0,1) == "A"){ digitalWrite(6, HIGH); digitalWrite(13, LOW); get_cv_data(); cv1_prog(); digitalWrite(6, LOW); digitalWrite(13, HIGH);} if (inString.substring(0,3) == "get"){ cv_val = 0; digitalWrite(6, HIGH); digitalWrite(13, LOW); get_cv_num(); cv_read(); digitalWrite(6, LOW); digitalWrite(13, HIGH); } if (inString.substring(0,3) == "add"){ cv_write_val = 0; digitalWrite(6, HIGH); digitalWrite(13, LOW); get_cv_new_val(); repeat_cv_write(); digitalWrite(6, LOW); digitalWrite(13, HIGH); } if (inString.substring(0,1) == "V"){ delay(50);bluetooth.print("CV1 updated"); Serial.println(Address);} // cv1 write if (inString.substring(0,1) == "E"){ digitalWrite(6, LOW); // logic control of DCC signal to low (off) digitalWrite(13, HIGH); // to brake, shorts out h-bridge o/p } // e-stop inString = ""; } void get_cv_new_val(){ Serial.println(inString); String cv_w =""; int x = inString.indexOf("new,") + 4; cv_w = inString.substring(x,x+3); Serial.println(cv_w); cv_write_val = cv_w.toInt(); Serial.print("cv_write_val: ");Serial.println(cv_write_val); String addr =""; int z = inString.indexOf("addr,") + 5; addr = inString.substring(z,z+1); Serial.println(addr); Address = addr.toInt(); Serial.print("Address: ");Serial.println(Address); } void get_cv_num(){ cv_write_val = 0; Serial.println(inString); String temp =""; int x = inString.indexOf(",") + 1; temp = inString.substring(x,8); Serial.println(temp); Address = temp.toInt(); Serial.print("Address: ");Serial.println(Address); } void get_cv_data(){ unsigned long z = inString.length(); int y = 0; int count = 0; String inChar; String temp =""; for (int i = 0; i<=z; i++){ inChar = inString.substring(i,i+1); if (inChar == ",") {count++;} if (inChar != "," && inChar != "A") {temp += inChar;} if (inChar == ",") {Address = (temp.toInt());y = y +1;temp = "";} } amend_len3(msg[1]); assemble_3_byte(); Serial.println(inString); } void string(){ unsigned long z = inString.length(); int y = 0; for (int i = 0; i<=5; i++){ a[i] = 0; } int count = 0; String inChar; String temp =""; for (int i = 0; i<=z; i++){ inChar = inString.substring(i,i+1); if (inChar == ",") { count++; } if (inChar != "," && inChar != "D") { temp += inChar; } if (inChar == ",") { a[y] = (temp.toInt()); y = y +1; temp = ""; } } if (count == 3){ //Serial.println(inString); //print_data(); amend_len3(msg[1]); assemble_3_byte(); } if (count == 4){ //Serial.println(inString); //print_data(); amend_len4(msg[1]); assemble_4_byte(); } //Serial.println(inString); //Serial.println(a[1]); // Serial.println(a[2]); //Serial.println(a[3]); //Serial.println(a[4]); //print_data(); } void amend_len4 (struct Message & x) { x.len = 4; //Serial.println(x.len); } void assemble_4_byte() { preamable_type = 0; // 16 x '1's noInterrupts(); msg[0].data[0] = B11111111; msg[0].data[1] = B00000000; msg[0].data[2] = B11111111; msg[1].data[0] = a[1]; msg[1].data[1] = a[2]; msg[1].data[2] = a[3]; msg[1].data[3] = ((a[1] ^ a[2])^ a[3]); interrupts(); } void amend_len3 (struct Message & x) { x.len = 3; //Serial.println(x.len); } void assemble_3_byte() { preamable_type = 0; // 16 x '1's noInterrupts(); msg[0].data[0] = B11111111; msg[0].data[1] = B00000000; msg[0].data[2] = B11111111; msg[1].data[0] = a[1]; msg[1].data[1] = a[2]; msg[1].data[2] = (a[1] ^ a[2]); msg[1].data[3] = 0; interrupts(); } void print_data(){ Serial.print(msg[1].data[0], DEC); Serial.print(","); Serial.print(msg[1].data[1], DEC); Serial.print(","); Serial.print(msg[1].data[2], DEC); Serial.print(","); Serial.print(msg[1].data[3], DEC); Serial.println(","); } //CV read void cv_current(){ for (int i = 1 ; i<=10 ; i++){ sensorValue = analogRead(A0); C = 10.8 * sensorValue ; // mA if (C >= Cs){ cv_logic = true; } delayMicroseconds(500); Serial.print("C = ");Serial.println(C); } } void cv_read(){ cv_val = 0; delay(200); current(); if(bluetooth.available() == true);{ bluetooth.print("reading.."); } Cs = C + 50; CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val0 = cv_calc(0); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val1 = cv_calc(1); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val2 = cv_calc(2); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val3 = cv_calc(3); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val4 = cv_calc(4); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val5 = cv_calc(5); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val6 = cv_calc(6); delay(10); } } CV_VAL = 99; for (int f = 1 ; f<=10 ; f++){ if (CV_VAL == 99){ cv_val7 = cv_calc(7); delay(10); } } Serial.print("cv_val0 ");Serial.println(cv_val0); Serial.print("cv_val1 ");Serial.println(cv_val1); Serial.print("cv_val2 ");Serial.println(cv_val2); Serial.print("cv_val3 ");Serial.println(cv_val3); Serial.print("cv_val4 ");Serial.println(cv_val4); Serial.print("cv_val5 ");Serial.println(cv_val5); Serial.print("cv_val6 ");Serial.println(cv_val6); Serial.print("cv_val7 ");Serial.println(cv_val7); int cv_val_total = cv_val0+cv_val1+cv_val2+cv_val3+cv_val4+cv_val5+cv_val6+cv_val7; cv_val = 0; if (cv_val0 == 1){ cv_val = cv_val + 1; } if (cv_val1 == 1){ cv_val = cv_val + 2; } if (cv_val2 == 1){ cv_val = cv_val + 4; } if (cv_val3 == 1){ cv_val = cv_val + 8; } if (cv_val4 == 1){ cv_val = cv_val + 16; } if (cv_val5 == 1){ cv_val = cv_val + 32; } if (cv_val6 == 1){ cv_val = cv_val + 64; } if (cv_val7 == 1){ cv_val = cv_val + 128; } if(bluetooth.available() == true);{ if (cv_val_total > 9){ bluetooth.print("read = error"); } if (cv_val_total < 9){ bluetooth.print("read = "); bluetooth.println(int(cv_val + 0.5)); } } Serial.print("cv_val ");Serial.println(int(cv_val + 0.5)); } void cv1_prog(){ for (int i = 0 ; i<=3 ; i++){ reset_packet(); delay(5); } for (int i = 0 ; i<=5 ; i++){ page_preset_packet(); delay(5); } for (int i = 0 ; i<=9 ; i++){ reset_packet(); delay(5); } for (int i = 0 ; i<=5 ; i++){ cv1_write_packet(); delay(5); } current(); for (int i = 0 ; i<=10 ; i++){ cv1_write_packet(); delay(5); } } void reset_packet() { noInterrupts(); preamable_type = 0; msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B00000000; msg[1].data[1] = B00000000; msg[1].data[2] = B00000000; interrupts(); } void page_preset_packet() { noInterrupts(); preamable_type = 0; // 16 x '1's msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B01111101; msg[1].data[1] = B00000001; msg[1].data[2] = B01111100; interrupts(); } void cv1_write_packet() { preamable_type = 1; // 24 x '1's noInterrupts(); msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B01111000; // Address only mode msg[1].data[1] = B00000000 | Address; msg[1].data[2] = (msg[1].data[0] ^ msg[1].data[1]); interrupts(); } void cv_verify1_packet() { noInterrupts(); preamable_type = 1; // 24 x '1's msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B01111000; // bit manipulation mode msg[1].data[1] = B00000000 | (Address -1); msg[1].data[2] = B11101000 | num; msg[1].data[3] = (msg[1].data[0] ^ msg[1].data[1]) ^ msg[1].data[2]; interrupts(); } void cv_verify0_packet() { noInterrupts(); preamable_type = 1; // 24 x '1's msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B01111000; // bit manipulation mode msg[1].data[1] = B00000000 | (Address -1); msg[1].data[2] = B11100000 | num; msg[1].data[3] = (msg[1].data[0] ^ msg[1].data[1]) ^ msg[1].data[2]; interrupts(); } void cv_write_packet() { preamable_type = 1; // 24 x '1's noInterrupts(); msg[0].data[0] = B11111111; msg[0].data[1] = B11111111; msg[0].data[2] = B11111111; msg[1].data[0] = B01111100; // write mode msg[1].data[1] = B00000000 | (Address -1); msg[1].data[2] = B00000000 | cv_write_val; msg[1].data[3] = (msg[1].data[0] ^ msg[1].data[1]) ^ msg[1].data[2]; interrupts(); } void valid_packet(){ noInterrupts(); msg[0].data[0] = B11111111; msg[0].data[1] = B00000000; msg[0].data[2] = B11111111; preamable_type = 0; // 16 x '1's msg[1].data[0] = (Address - 1); msg[1].data[1] = 0x80; // locoMsg with group one instruction 0x80 msg[1].data[2] = msg[1].data[0] ^ msg[1].data[1]; msg[1].data[3] = 0; interrupts(); } //CV write void repeat_cv_write() { current(); Cs = C + 50; Serial.print("C = ");Serial.println(C); Serial.print("Cs = ");Serial.println(Cs); if(bluetooth.available() == true);{ bluetooth.print("writing.."); } ok = false; for (int f = 1 ; f<=10 ; f++){ if (ok == false){ cv_write(); delay(10); } } } void cv_write(){ delay(100); amend_len3(msg[1]); assemble_3_byte(); delay(5); for (int i = 1 ; i<=20 ; i++){ valid_packet(); delay(5); } for (int i = 1 ; i<=6 ; i++){ reset_packet(); delay(5); } cv_logic = false; amend_len4(msg[1]); assemble_4_byte(); for (int i = 1 ; i<=10 ; i++){ cv_write_packet(); cv_current(); Serial.print("C= ");Serial.println(C); if (cv_logic){ ok = true; cv_logic = false; i = 11; amend_len3(msg[1]); assemble_3_byte(); for (int i = 1 ; i<=10 ; i++){ reset_packet(); delay(5); } if(bluetooth.available() == true);{ bluetooth.print("write = "); bluetooth.println(cv_write_val); Serial.print("cv_write_val ");Serial.println(cv_write_val); } } } if(bluetooth.available() == true);{ if (ok == false){ bluetooth.print("write = error"); } } } int cv_calc(int test_num) { amend_len3(msg[1]); assemble_3_byte(); delay(5); for (int i = 1 ; i<=20 ; i++){ valid_packet(); delay(5); } num = test_num; amend_len3(msg[1]); assemble_3_byte(); for (int k = 1 ; k<=4 ; k++){ reset_packet(); delay(5); } amend_len4(msg[1]); assemble_4_byte(); cv_logic = false; delay(2); for (int m = 1 ; m<=5 ; m++){ cv_verify1_packet(); cv_current(); if (cv_logic){ cv_logic = false; CV_VAL = 1; Serial.print("test_num = ");Serial.println(test_num); Serial.println(CV_VAL); preamable_type = 0; amend_len3(msg[1]); assemble_3_byte(); delay(5); for (int j = 1 ; j<=3 ; j++){ reset_packet(); delay(5); } } } Serial.println("test for 0 "); amend_len3(msg[1]); assemble_3_byte(); for (int k = 1 ; k<=4 ; k++){ reset_packet(); delay(5); } amend_len4(msg[1]); assemble_4_byte(); cv_logic = false; delay(2); for (int m = 1 ; m<=5 ; m++){ cv_verify0_packet(); cv_current(); if (cv_logic){ cv_logic = false; CV_VAL = 0; Serial.print("test_num = ");Serial.println(test_num); Serial.println(CV_VAL); preamable_type = 0; amend_len3(msg[1]); assemble_3_byte(); delay(5); for (int j = 1 ; j<=3 ; j++){ reset_packet(); delay(5); } } } Serial.println(CV_VAL); return CV_VAL; }
Bagian dan Kotak Pelindung Kustom
Sirkuit lengkap dalam kotak pelindung
Skematik
Sirkuit penerima Bluetooth / penguat H-bridgebluetooth_android_dcc_lmd18200_S8NTVsI4LY.fzzInstruksi Aplikasi