//11111111111111 0 00001001 0 01110101 0 10011001 0 10110000 0 10111001 1 0000//14 bit preable address 9 speed 9 ^ ^ F5-F8 checksum 4 trailing 0's// | |// headlight // |// F1-F4
void assemblePackets() { byte speed_tmp; // make local variable for speed to calculate with /****** ADDRES *******/ packetAddres = addres; /****** SPEED *******/ speed_tmp = train[addres].speed; // store speed in 'speed_tmp' to calculate with packetSpeed = 0; // clear byte for re-usage if(speed_tmp < 0) { packetSpeed |= REVERSE; // set flag for reverse speed direction speed_tmp ^= 0xff; // invert the byte if is negative to positive using XOR speed_tmp++; } else { packetSpeed |= FORWARD; } // set flag for forward speed direction packetSpeed |= (speedTable[speed_tmp + 4] & 0b11111l); // first 4 speed steps are (E)stop commands, the last 5 bytes contain the speed information /****** FUNCTIONS F1 - F4 *******/ packetFunctions1 = 0; // clear byte for re-usage packetFunctions1 |= FUNCTIONS1; // mark this as instructions byte if(train[addres].headLight) packetFunctions1 |= (1<<4); // turns on headlight packetFunctions1 |= (train[addres].functions & 0x0F); // F1 - F4 /****** FUNCTIONS F5 - F8 *******/ packetFunctions2 = 0; // clear byte for re-usage packetFunctions2 |= FUNCTIONS2; // mark this as instructions byte packetFunctions1 |= ((train[addres].functions & 0xF0) >> 4); // F5 - F8 /***** CHECKSUM *******/ packetChecksum = packetAddres ^ packetFunctions2; //packetAddres ^ packetSpeed also tried.. must I send 3 checksum bytes? /***** SHIFT PACKETS FOR TRACK SIGNAL *******/ bitArray[0] = 0xFF; bitArray[1] = 0xFC; // pre-amble + 2 0 bits bitArray[2] = packetAddres << 1; bitArray[3] = packetSpeed; bitArray[4] = packetFunctions1 >> 1; bitArray[5] = packetFunctions1 << 7 | packetFunctions2 >> 2; bitArray[6] = packetFunctions2 << 6 | packetChecksum >> 3; bitArray[7] = packetChecksum << 5 | 1<<4; }
ISR(TIMER1_COMPB_vect){ if(ISR_state == 0){ // pick a bit and set duration time accordingly ISR_state = 1; Bit = (*ptr & (0x80 >> bitCounter)) >> (7-bitCounter); // select the next bit out of bitArray if(Bit == 1) OCR1A=DCC_ONE_BIT; // '1' 58us else OCR1A=DCC_ZERO_BIT; // '0' 116us // Serial.print(Bit); // enabling this, showed me that the the variable 'Bit' is always what it should be bitCounter++; if(bitCounter==8) { bitCounter = 0; ptr++; // select the next byte from bitArray if(ptr == (&bitArray[7] + 1)) { // if last byte is done ptr = &bitArray[0]; OCR1A = 0xFFFF; // temporarily susppend ISR by setting compare register at 0xfff untill the main routine has assembled a new package packetSent = 1;} } } else { ISR_state = 0; PORTB ^= 0X3; } // toggle pin 8 and 9 for direction}
void nextPacket(){ packetSent = 0; ptr = &bitArray[0]; // set the pointer back to the first bit bitCounter = 0; addres++; // if it is sent, increment addres if(addres > 10) addres = 1; // address range is 1-80 assemblePackets(); // assemble a new package Serial.println(); Serial.println(addres); OCR1A=927; }void loop() { readSerialBus(); shortCircuit(); EstopPressed(); if(packetSent) nextPacket();}
Dus mijn eerste vraag: stel ik de data pakketten goed samen?
{preamble} 0 AAAAAAAA 0 CCCDDDDD 0 EEEEEEEE 111111111111111 0 00001001 0 01110101 0 01111100 1Preamble | | | | | | start | | | | addres 9 | | | | 011 = Speed and Direction Instruction for forward operation Speed 8 | | Error = XOR Stop
{preamble} 0 AAAAAAAA 0 CCCDDDDD 0 EEEEEEEE 111111111111111 0 00001001 0 10011001 0 10010000 1Preamble | | | || | | start | || | | addres 9 | || | | Function Group One Instruction F0 = on | | F4 = on, F3 = off, F2 = off, F1 = on Error = XOR Stop
Moet ik nu voor de checksum 1 byte sturen of 3 bytes?
packetSent = 1;} } }
Bit: Waarom niet bit?
ISR_state: Probeer zelf altijd één stijl aan te houden, dus waarom niet IsrState?
DCC_ONE_BIT / DCC_ZERO_BIT: ziet er uit als een macro, weet dat C++ ook const kent
(&bitArray[7] + 1)) mag ook zijn &bitArray[8] maar zou het denk ik zelf als constante buiten de IRS om definiëren om flexibel te blijven.
ptr: gebruik je deze ook nog buiten de ISR? Zo ja, dan moet je de ISR uitschakelen tijdens het lezen. Als anders de ISR vuurt als je aan het lezen bent ben je namelijk in de aap gelogeerd daar een pointer niet atomic is
En owCode: [Selecteer] packetSent = 1;} } }Het maakt niet uit welke stijl van C je schrijft, dat is een doodzonde Sluithaken altijd op een nieuwe regel in lijn met het begin van de regel waar de openingshaak staat. Maakt het ook zooooo veel leesbaarder
iig erg bedankt voor je antwoord. Ik dacht dat ik zoveel instructie bytes kon sturen als ik wilde. Dat leek me ook logisch omdat de decoder kan synchorniseren na elke byte en je niet telkens de pre-amble hoeft te versturen.
a packet using the extended packet format definition may have a length of between 3 and 6 data bytes each separated by a "0" bit.
Naja, da's een makkelijke. Ik maak dit in de arduino ide en dat komt zo heel af en toe met een haak en een oog. 'bit' wordt namelijk gehighlight in de ide. 'speed' die ik ook gebruik, wordt ook gehighlight alleen die kan je wel gebruiken. Arduino's ide kennende, zal bit wel bedoeld zijn om een soort bit variabele te maken of weet ik veel waar het 'bit' keyword voor gebruikt wordt
const bool b= (*ptr & (0x80 >> bitCounter)); // select the next bit out of bitArray//laatste shift is niet nodig
ISR(TIMER1_COMPB_vect){ static byte bitMask = 0x80; if(ISR_state == 0){ // pick a bit and set duration time accordingly ISR_state = 1; if(*ptr & bitMask){ OCR1A = DCC_ONE_BIT; // '1' 58us } else{ OCR1A = DCC_ZERO_BIT; // '0' 116us } // Serial.print(Bit); // enabling this, showed me that the the variable 'Bit' is always what it should be //BUT a serial print from a ISR is a bad idea and fails A LOT bitMask >>= 1; if(!bitMask) { bitMask = 0x80;;
Ja ik dacht er aan dat het hier wel kon, [...]
byte packetArray[7];byte * const PacketEndPtr = &packetArray[sizeof(packetArray)];//of waarom eigenlijk nog losse pointers aanmaken, een array is al een pointer constructieconst byte PacketArraySize = 7;byte packetArray[PacketArraySize];//en gewoon een iterator in de ISR
[...]Maar ik denk wel dat ik dat ombouw naar echt de ISR uitzetten, dat is zeker veel beter en veiliger.Dit is echt mijn beste uitvinding ooit. Ik had ooit ff in Python gespeeld en daar waren geen accolades. Die bestonden net zo min als end of line markers ;
Weet dat, omdat je het nog nooit gezien heb of dat omdat het door de grote menigte niet is aangenomen of omdat het je raar lijkt, het niet noodzakelijk iets slechts is. Ik ben er al een lange tijd achter dat de beslissingen die de grote groepen nemen of beslissingen die lange tijden zijn genomen niet ook meteen de beste of goede beslissingen waren.
Ik zal mijn code aanpassen. En misschien dat ik de andere kant van de H-brug ga gebruiken omdat deze kant misschien niet helemaal meer werkt
byte speedBlob = speedStep + 3;speedblob = (speedBlob >> 1) | ((speedBlob & 0x01) << 4);
Top!Dat snelheid blobje is inderdaad een chaos Maar iets alsCode: [Selecteer]byte speedBlob = speedStep + 3;speedblob = (speedBlob >> 1) | ((speedBlob & 0x01) << 4);Timo
byte speedTable[] = { 0b00000/*Stop */ ,0b00100/* 5 */ ,0b01000/* 13 */ ,0b01100/* 21 */,0b10000/*Stop1*/ ,0b10100/* 6 */ ,0b11000/* 14 */ ,0b11100/* 22 */,0b00001/*Estop*/ ,0b00101/* 7 */ ,0b01001/* 15 */ ,0b01101/* 23 */,0b10001/*Estop*/ ,0b10101/* 8 */ ,0b11001/* 16 */ ,0b11101/* 24 */,0b00010/* 1 */ ,0b00110/* 9 */ ,0b01010/* 17 */ ,0b01110/* 25 */,0b10010/* 2 */ ,0b10110/* 10 */ ,0b11010/* 18 */ ,0b11110/* 26 */,0b00011/* 3 */ ,0b00111/* 11 */ ,0b01011/* 19 */ ,0b01111/* 27 */,0b10011/* 4 */ ,0b10111/* 12 */ ,0b11011/* 20 */ ,0b11111/* 28 */};
#define FORWARD 0b01100000#define REVERSE 0b01000000speed_tmp = train[addres].speed; // store speed in 'speed_tmp' to calculate with packetSpeed = 0; // clear byte for re-usage if(speed_tmp < 0) { packetSpeed |= REVERSE; // set flag for reverse speed direction speed_tmp ^= 0xff; // invert the byte if is negative to positive using XOR speed_tmp++; } else { packetSpeed |= FORWARD; } // set flag for forward speed direction packetSpeed |= (speedTable[speed_tmp + 3]);
Ow, LOLLL Toen wilde ik send drukken maar zie ik je fout Je hebt de speed tabel letterlijk overgenomen uit het DCC document. Maar C/C++ leest natuurlijk niet boven naar beneden, links naar rechts Die leest van links naar rechts, van boven naar beneden Dus als je speedstep 10 hebt kom je uit bij '0b10101/* 8 */' Geen wonder dat je loc bokkensprongen staat te maken!