Optokobler 6N137 DIP8 – 1 Kanal kan bruges til mange forskellige formål. En af dem kunne være at opsamle DCC signalet fra skinnerne i et togskinne system.
En optokobler er en elektronisk komponent eller 2 delkredsløb, som ved hjælp af optiske signaler (lysimpulser) tillader overførsel (envejskobling) af (fortrinsvis digitale) elektriske signaler mellem to kredsløb, der er elektrisk isoleret fra hinanden.
Tekniske detaljer:
Operating Temperature Max: 85°C
Operating Temperature Min: -40°C
Input Type: DC
Power: 7V (Max)
Voltage Operating: 1.38V (Husk modstand)
Current – Output / Channel: 50mA
Installere Arduino IDE Software
Før du kan starte din programmering skal Arduino’s IDE software hentes. Dette program bruges til at programmere chippen.
Download fra dette link: Downlaod
Installere NmraDcc-master Library
- Download library (Download)
- Udpak filer
- Flyt/kopir mappen “NmraDcc-master” til “libraries” som findes i “Arduino IDE” mappen (C:Program Files (x86)Arduinolibraries)
- Åben Arduino IDE software og klik på “Sketch/Include library”
- Klik nu på “Add Zip. library” og find Zip filen du lige har downloaded.
- Åben “Sketch/Include library/Manage Librarys” for at opdatere library.
- Luk, og åben Arduino IDE programmet. (Genstart programmet)
- Nu er “NmraDcc-master” installeret
Programmering
Inden programmeringen kan udfæres skal den rigtige “COM” port findes. Klik “Værktøj/Port” – og vælg COM port.
Eksempel:
Her vises et eksempel på hvordan du læser DCC signalet (togskinner) og sender det til en arduino.
Du skal bruge:
- Arduino Uno R3
- 2x 10K Modstand
- 1.5K Modstand
- 1N4148 DO-35 Switching Signal Doide
Kode: (Addresse Sniffer)
Brug denne sniffer kode til at se hvilken adresser som køre på systemet. dataerne vil blive vist i “Serial monitor” i arduino IDE (Værktøjer/Serial monitor). Vælg baud 38400. i serial monitoren. Tryk efter uploading på et skiftespor.
byte refreshTime = 3; // Time between DCC packets buffer refreshes in s byte packetBufferSize = 16; // DCC packets buffer size #define TIMER_PRESCALER 64 #define DccBitTimerCount (F_CPU * 80L / TIMER_PRESCALER / 1000000L) // 16000000 * 80 / 64 / 1000000 = 20; 20 x 4usecs = 80us boolean packetEnd; boolean preambleFound; const byte bitBufSize = 50; // number of slots for bits volatile byte bitBuffer[bitBufSize]; volatile byte bitBuffHead = 1; volatile byte bitBuffTail = 0; byte pktByteCount=0; byte packetBytesCount; byte preambleOneCount; byte dccPacket[6]; // buffer to hold a packet byte instrByte1; byte decoderType; //0=Loc, 1=Acc byte bufferCounter=0; byte isDifferentPacket=0; byte showLoc=1; byte showAcc=1; unsigned int decoderAddress; unsigned int packetBuffer[64]; unsigned int packetNew=0; unsigned long timeToRefresh = millis() + refreshTime*1000; //======================== void getPacket() { preambleFound = false; packetEnd = false; packetBytesCount = 0; preambleOneCount = 0; while (! packetEnd) { if (preambleFound) getNextByte(); else checkForPreamble(); } } //======================== void checkForPreamble() { byte nextBit = getBit(); if (nextBit == 1) preambleOneCount++; if (preambleOneCount < 10 && nextBit == 0) preambleOneCount = 0; if (preambleOneCount >= 10 && nextBit == 0) preambleFound = true; } //======================== void getNextByte() { byte newByte = 0; for (byte n = 0; n < 8; n++) newByte = (newByte << 1) + getBit(); packetBytesCount ++; dccPacket[packetBytesCount] = newByte; dccPacket[0] = packetBytesCount; if (getBit() == 1) packetEnd = true; } //======================== byte getBit() { // gets the next bit from the bitBuffer // if the buffer is empty it will wait indefinitely for bits to arrive byte nbs = bitBuffHead; while (nbs == bitBuffHead) byte nbs = nextBitSlot(bitBuffTail); //Buffer empty bitBuffTail = nbs; return (bitBuffer[bitBuffTail]); } //======================== void beginBitDetection() { TCCR0A &= B11111100; attachInterrupt(0, startTimer, RISING); } //======================== void startTimer() { OCR0B = TCNT0 + DccBitTimerCount; TIMSK0 |= B00000100; TIFR0 |= B00000100; } //======================== ISR(TIMER0_COMPB_vect) { byte bitFound = ! ((PIND & B00000100) >> 2); TIMSK0 &= B11111011; byte nbs = nextBitSlot(bitBuffHead); if (nbs == bitBuffTail) return; else { bitBuffHead = nbs; bitBuffer[bitBuffHead] = bitFound; } } //======================== byte nextBitSlot(byte slot) { slot ++; if (slot >= bitBufSize) slot = 0; return(slot); } //======================== void printPacket() { Serial.print(" "); for (byte n=1; n<pktByteCount; n++) { Serial.print(" "); Serial.print(dccPacket[n],BIN); } Serial.println(" "); } //======================== void refreshBuffer() { timeToRefresh = millis() + refreshTime*1000; for (byte n=0; n<packetBufferSize; n++) packetBuffer[n]=0; bufferCounter=0; Serial.println("-"); /* Serial.print("Loc "); Serial.print(showLoc); Serial.print(" / Acc "); Serial.print(showAcc); Serial.print(" / Time "); Serial.print(refreshTime); Serial.print(" / Buff "); Serial.println(packetBufferSize); Serial.println(" "); */ } //======================== void setup() { Serial.begin(38400); // 38400 when on DCC, 9600 when testing on 123Circuits !!!!!!!!!!!!!!!!!!!!!!! Serial.println("---"); Serial.println("DCC Packet Analyze started"); Serial.print("Updates every "); Serial.print(refreshTime); Serial.println(" seconds"); Serial.println("---"); beginBitDetection(); //Uncomment this line when on DCC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } //==================== void loop() { getPacket(); //Uncomment this line when on DCC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! byte speed; byte checksum = 0; if (millis() > timeToRefresh) refreshBuffer(); /* Dummy packet for test purposes. Comment when on DCC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Loc 1782 CV Write 3 128 dccPacket[0]=6; dccPacket[1]=B11000111; dccPacket[2]=B01101110; dccPacket[3]=B11101100; dccPacket[4]=B00000011; dccPacket[5]=B10000000; dccPacket[6]=B11111111; */ pktByteCount = dccPacket[0]; if (!pktByteCount) return; // No new packet available for (byte n = 1; n <= pktByteCount; n++) checksum ^= dccPacket[n]; //checksum=0; //Comment this line when on DCC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (checksum) return; // Invalid Checksum else { // There is a new packet with a correct checksum isDifferentPacket=1; for (byte n=0; n<packetBufferSize ; n++) {// Check if packet is not already in the buffer. // The checksum byte is used for the test, not ideal, some new packets may not show (only 256 different checksums) if (dccPacket[pktByteCount]==packetBuffer[n]) isDifferentPacket=0; } if (isDifferentPacket) { // packet does not yet exist in the packet buffer packetBuffer[bufferCounter] = dccPacket[pktByteCount]; // add new packet to the buffer bufferCounter = (++bufferCounter)&(packetBufferSize-1); if (dccPacket[1]==B11111111) { //Idle packet Serial.println("Idle "); return; } if (!bitRead(dccPacket[1],7)) { //bit7=0 -> Loc Decoder Short Address decoderAddress = dccPacket[1]; instrByte1 = dccPacket[2]; decoderType = 0; } else { if (bitRead(dccPacket[1],6)) { //bit7=1 AND bit6=1 -> Loc Decoder Long Address decoderAddress = 256 * (dccPacket[1] & B00000111) + dccPacket[2]; instrByte1 = dccPacket[3]; decoderType = 0; } else { //bit7=1 AND bit6=0 -> Accessory Decoder decoderAddress = dccPacket[1]&B00111111; instrByte1 = dccPacket[2]; decoderType = 1; } } if (decoderType) { // Accessory Basic if (showAcc) { if (instrByte1&B10000000) { // Basic Accessory decoderAddress = (((~instrByte1)&B01110000)<<2) + decoderAddress; byte port = (instrByte1&B00000110)>>1; Serial.print("Acc "); Serial.print((decoderAddress-1)*4 + port + 1); Serial.print(" "); Serial.print(decoderAddress); Serial.print(":"); Serial.print(port); Serial.print(" "); Serial.print(bitRead(instrByte1,3)); if (bitRead(instrByte1,0)) Serial.print(" On"); else Serial.print(" Off"); } else { // Accessory Extended NMRA spec is not clear about address and instruction format !!! Serial.print("Acc Ext "); decoderAddress = (decoderAddress<<5) + ((instrByte1&B01110000)>>2) + ((instrByte1&B00000110)>>1); Serial.print(decoderAddress); Serial.print(" Asp "); Serial.print(dccPacket[3],BIN); } printPacket(); } } else { // Loc / Multi Function Decoder if (showLoc) { Serial.print("Loc "); Serial.print(decoderAddress); byte instructionType = instrByte1>>5; switch (instructionType) { case 0: Serial.print(" Control "); break; case 1: // Advanced Operations if (instrByte1==B00111111) { //128 speed steps if (bitRead(dccPacket[pktByteCount-1],7)) Serial.print(" Forw128 "); else Serial.print(" Rev128 "); byte speed = dccPacket[pktByteCount-1]&B01111111; if (!speed) Serial.print(" Stop "); else if (speed==1) Serial.print(" E-stop "); else Serial.print(speed-1); } else if (instrByte1==B00111110) { //Speed Restriction if (bitRead(dccPacket[pktByteCount-1],7)) Serial.print(" On "); else Serial.print(" Off "); Serial.print(dccPacket[pktByteCount-1])&B01111111; } break; case 2: // Reverse speed step speed = ((instrByte1&B00001111)<<1) - 3 + bitRead(instrByte1,4); if (speed==253 || speed==254) Serial.print(" Stop "); else if (speed==255 || speed==0) Serial.print(" E-Stop "); else { Serial.print(" Rev "); Serial.print(speed); } break; case 3: // Forward speed step speed = ((instrByte1&B00001111)<<1) - 3 + bitRead(instrByte1,4); if (speed==253 || speed==254) Serial.print(" Stop "); else if (speed==255 || speed==0) Serial.print(" E-Stop "); else { Serial.print(" Forw "); Serial.print(speed); } break; case 4: // Loc Function L-4-3-2-1 Serial.print(" L F4-F1 "); Serial.print(instrByte1&B00011111,BIN); break; case 5: // Loc Function 8-7-6-5 if (bitRead(instrByte1,4)) { Serial.print(" F8-F5 "); Serial.print(instrByte1&B00001111,BIN); } else { // Loc Function 12-11-10-9 Serial.print(" F12-F9 "); Serial.print(instrByte1&B00001111,BIN); } break; case 6: // Future Expansions switch (instrByte1&B00011111) { case 0: // Binary State Control Instruction long form Serial.print(" BinStateLong "); Serial.print(256 * dccPacket[pktByteCount-1] + (dccPacket[pktByteCount-2]&B01111111)); if bitRead(dccPacket[pktByteCount-2],7) Serial.print(" On "); else Serial.print(" Off "); break; case B00011101: // Binary State Control Serial.print(" BinStateShort "); Serial.print(dccPacket[pktByteCount-1]&B01111111); if bitRead(dccPacket[pktByteCount-1],7) Serial.print(" On "); else Serial.print(" Off "); break; case B00011110: // F13-F20 Function Control Serial.print(" F20-F13 "); Serial.print(dccPacket[pktByteCount-1],BIN); break; case B00011111: // F21-F28 Function Control Serial.print(" F28-F21 "); Serial.print(dccPacket[pktByteCount-1],BIN); break; } break; case 7: Serial.print(" CV "); if (instrByte1&B00010000) { // CV Short Form byte cvType=instrByte1&B00001111; switch (cvType) { case B00000010: Serial.print("23 "); Serial.print(dccPacket[pktByteCount-1]); break; case B00000011: Serial.print("24 "); Serial.print(dccPacket[pktByteCount-1]); break; case B00001001: Serial.print("Decoder Lock "); Serial.print(dccPacket[pktByteCount-1]); break; } } else { // CV Long Form int cvAddress = 256 * (instrByte1&B00000011) + dccPacket[pktByteCount-2] + 1; Serial.print(cvAddress); Serial.print(" "); switch (instrByte1&B00001100) { case B00000100: // Verify Byte Serial.print("Verify "); Serial.print(dccPacket[pktByteCount-1]); break; case B00001100: // Write Byte Serial.print("Write "); Serial.print(dccPacket[pktByteCount-1]); break; case B00001000: // Bit Write Serial.print("Bit "); if (dccPacket[pktByteCount-2]&B00010000) Serial.print("Verify "); else Serial.print("Write "); Serial.print(dccPacket[pktByteCount-1]&B00000111); Serial.print(" "); Serial.print((dccPacket[pktByteCount-1]&B00001000)>>3); break; } } break; } printPacket(); } } } } if (Serial.available()) { Serial.println(" "); switch (Serial.read()) { case 49: Serial.println("Refresh Time = 1s"); refreshTime=1; break; case 50: Serial.println("Refresh Time = 2s"); refreshTime=2; break; case 51: Serial.println("Refresh Time = 4s"); refreshTime=4; break; case 52: Serial.println("Refresh Time = 8s"); refreshTime=8; break; case 53: Serial.println("Refresh Time = 16s"); refreshTime=16; break; case 54: Serial.println("Buffer Size = 4"); packetBufferSize=2; break; case 55: Serial.println("Buffer Size = 8"); packetBufferSize=8; break; case 56: Serial.println("Buffer Size = 16"); packetBufferSize=16; break; case 57: Serial.println("Buffer Size = 32"); packetBufferSize=32; break; case 48: Serial.println("Buffer Size = 64"); packetBufferSize=64; break; case 97: if (showAcc) showAcc=0; else showAcc=1; Serial.print("show loc packets = "); Serial.println(showAcc); break; case 108: if (showLoc) showLoc=0; else showLoc=1; Serial.print("show loc packets = "); Serial.println(showLoc); break; } Serial.println(" "); } }
Kode (Styring)
Upload efter denne kode til skiftespor controllering.
- #define DCC_PIN = Den pin på arduino som modtager DCC signalet (Pin 2)
- #define BOARD_ADDRESS = Adressen på skiftestoret, IKKE tog addressen.
- #define PAIR_ADDRESS = Under address, bruges til ON/OFF værdi.
I denne kode har jeg valg inde i min app, at sporskifte 1 har addressen 1. (BOARD_ADDRESS)
#include <NmraDcc.h> NmraDcc Dcc; // definitions #define DCC_PIN 2 #define BOARD_ADDRESS 1 #define PAIR_ADDRESS 1 #define GREEN_LED_PIN 3 #define RED_LED_PIN 4 void notifyDccAccState(uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State) { int pairAddress = (OutputAddr >> 1) + 1; int outputInPair = OutputAddr & 0x01; Serial.print("* new accessory decoder packet received (BoardAddr="); Serial.print(BoardAddr, DEC); Serial.print(", pairAddress="); Serial.print(pairAddress, DEC); Serial.print(", outputInPair="); Serial.println(outputInPair, DEC); // check if the command is for our address and output if((BoardAddr == BOARD_ADDRESS) && (pairAddress == PAIR_ADDRESS)) { if(outputInPair == 0) { digitalWrite(RED_LED_PIN, HIGH); digitalWrite(GREEN_LED_PIN, LOW); Serial.println("! RED led activated"); } else { digitalWrite(RED_LED_PIN, LOW); digitalWrite(GREEN_LED_PIN, HIGH); Serial.println("! GREEN led activated"); } } } void setup() { // Serial output for debugging Serial.begin(115200); Serial.println("DCC Led Accessory Decoder"); Serial.println(); // init NmraDcc library (PIN, manufacturer, version...) Dcc.pin(digitalPinToInterrupt(DCC_PIN), DCC_PIN, 1); Dcc.init(MAN_ID_DIY, 1, FLAGS_DCC_ACCESSORY_DECODER, 0); // configure pins pinMode(GREEN_LED_PIN, OUTPUT); pinMode(RED_LED_PIN, OUTPUT); Serial.println("- decoder ready"); } void loop() { Dcc.process(); }
Download
Kontakt os
Du er altid velkommen til at kontakte os på info@ardustore.dk, eller sende os en besked via messenger (Klik her) og vi vil hjælpe dig.
Anmeldelser
Der er endnu ikke nogle anmeldelser.