Jump to content

Raspberry Pi DCC commander


PizzaBoy150

Recommended Posts

Hi All,

I thought it would be a fun project to create a dcc commander using a raspberry pi to control my railway. I am using hornby decoders though.

I have created a h bridge circuit with a 12v supply to power it and the h bridge is controlled using the gpio pins on the raspberry pi to create my +/- 12v square wave.

The hbridge seems to be working perfectly and i have writted a simple program in c++ to control the pins and send the packet to the train.

Though it seems to be functioning more in dc mode than dcc..?

I am assuming that the default address of the train is 3? and the documentation i am using is NMRA standard.

I have placed the code below to see if anyone can spot my errors?

All help and ideas welcome

#include <iostream>
#include <unistd.h>
#include "wiringPi.h"

using namespace std;

//wiring pi pin numbers
int pinA = 8;
int pinB = 9;

char packet[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0, 0,0,0,0,0,0,1,1, 0, 0,1,1,1,0,0,1,0, 1};

void sendPacket() {

int length = sizeof(packet) / sizeof(char);

//loop through sending bits
for(int i = 0; i < length; i++) {

//check for 1 or 0?
if(packet == 1) {
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
usleep(56);
digitalWrite(pinB, LOW);
digitalWrite(pinA, HIGH);
usleep(56);
}
else {
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
usleep(100);
digitalWrite(pinB, LOW);
digitalWrite(pinA, HIGH);
usleep(100);

}
usleep(1000);
}
}

int main(int argc, char *argv[]) {

//Start library
wiringPiSetup();

//setup the pins
pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);


while(1) {
sendPacket();
}

return 0;
}

Link to comment
Share on other sites

I’m also not able to decipher PB’s code to see if it is correct. However, I can put HB’s concern to rest as PB says he is first generating a square wave and I’m assuming his programming is modulating that with a packet to send to the loco.

 

PB, the fact you say it is behaving more like DC is probably DC Runaway caused by the decoder not recognizing yours as being a DCC signal and so assuming it is DC.  Does your loco take off like a scalded cat and only stop when you remove power?

Link to comment
Share on other sites

thanks for the response, i definately have a square wave and the code is running as desired, i think its the packet im sending is incorrect. The hornby decoder defaults to the 128 speed step in the datasheet and im not error checking correctly.

does anyone have a packet example for 128 speed step?

it should be somthing like

preamble

1 1 1 1 1 1 1 1 1 1 end bit 0

addres

0 0 0 0 0 0 1 1 end bit 0

data byte start

0 1 ? ? ? ? ? ? end bit 0

second data bit

? ? ? ? ? ? ? ? end bit 0

error XOR of address and data

? ? ? ? ? ? ? ? end packet 1

 

Link to comment
Share on other sites

it looks to me that your packet will transmit as all '1's and no '0's because of the bug in line 16.

 

try changing it to   if(packet == 1) {

thats a condition statement if the number in the packet is equal to 1 it will transmit a 1 bit else { it will transmit a 0 bit } in the else block below.

 

I know the code is correct and its the data in packet which is incorrect

Link to comment
Share on other sites

I’m also not able to decipher PB’s code to see if it is correct. However, I can put HB’s concern to rest as PB says he is first generating a square wave and I’m assuming his programming is modulating that with a packet to send to the loco.

 

PB, the fact you say it is behaving more like DC is probably DC Runaway caused by the decoder not recognizing yours as being a DCC signal and so assuming it is DC.  Does your loco take off like a scalded cat and only stop when you remove power?

yes it just runs away full speed until i disconnect

Link to comment
Share on other sites

 yes,

the line    if(packet == 1) {       is testing to see if packet is equal to 1, but packet is actually '111111111111110000000110011100101' so the statement always returns false and the code goes through the else section.

by putting the [ i ] , each iteration through the loop will test the next element in the array.

for instance packet [0] is equal to 1

but packet[14] is equal to zero

 

Link to comment
Share on other sites

 yes,

the line    if(packet == 1) {       is testing to see if packet is equal to 1, but packet is actually '111111111111110000000110011100101' so the statement always returns false and the code goes through the else section.

by putting the [ i ] , each iteration through the loop will test the next element in the array.

for instance packet [0] is equal to 1

but packet[14] is equal to zero

 

I see when i pasted my code it removed the square brackets for packet they are there in the actual code so it is iterating through the code as desired. Its the format of the packet I am sending which is the issue.

 

Link to comment
Share on other sites

ok, so it should start with 10 '1's followed by a zero, then three 8-bit sections, each terminated by a zero

i would guess that the packet should be:

{1,1,1,1,1,1,1,1,1,1, 0,  0,0,0,0,0,0,1,1,  0,  0,1,1,1,0,0,1,0,  0,1,1,1,0,0,0,1, 1};

i've reduced the number of '1's at the start to ten, then created the xor stream of 8 bits at the end....

Link to comment
Share on other sites

finally working as desired, yay!

the problem was the delay function i used the one included in wiring pi and it worked!

updated code below, thanks chaps!!

 

  1. #include #include
  2. using namespace std;
  3. //wiring pi pin numbersint pinA = 2;int pinB = 0;
  4. char packet[] = {1,1,1,1,1,1,1,1,1,1,1,1, 0, 0,0,0,0,0,0,1,1, 0, 0,1,0,0,0,0,1,1, 0, 0,1,0,0,0,0,0,0, 1};
  5. void sendPacket() { int length = sizeof(packet) / sizeof(char); //loop through sending bits for(int i = 0; i < length; i++) {
  6. //check for 1 or 0? if(packet == 1) { digitalWrite(pinA, LOW); digitalWrite(pinB, HIGH); delayMicroseconds(58); digitalWrite(pinB, LOW); digitalWrite(pinA, HIGH); delayMicroseconds(58); } else { digitalWrite(pinA, LOW); digitalWrite(pinB, HIGH); delayMicroseconds(100); digitalWrite(pinB, LOW); digitalWrite(pinA, HIGH); delayMicroseconds(100);
  7. } }}
  8. int main(int argc, char *argv[]) {
  9. //Start library wiringPiSetup();
  10. //setup the pins pinMode(pinA, OUTPUT); pinMode(pinB, OUTPUT);
  11. while(1) { sendPacket(); }
  12. return 0;}
Link to comment
Share on other sites

Can I suggest when you do that you post it in the "Off Topic" sub-forum. There are a few electronic projects in that section already and interesting posts stay visible longer as it is a slow moving forum section.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
  • Create New...