Pages: [1] 2   Go Down
Author Topic: Railstars CmdrArduino lib help  (Read 2685 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been trying to get a model train DCC command station library running, but I'm having problems getting past the initialisation routine.

The lib is available from - https://github.com/Railstars/CmdrArduino

It's generating a DCC pulse train ok, but it doesn't seem to be getting past this function in DCCPacketScheduler.cpp,
Code:
void DCCPacketScheduler::setup(void) //for any post-constructor initialization
{
  setup_DCC_waveform_generator();
 
  //Following RP 9.2.4, begin by putting 20 reset packets and 10 idle packets on the rails.
  //use the e_stop_queue to do this, to ensure these packets go out first!
 
  DCCPacket p;
  byte data[] = {0x00};
 
  //reset packet: address 0x00, data 0x00, XOR 0x00; S 9.2 line 75
  p.addData(data,1);
  p.setAddress(0x00);
  p.setRepeat(20);
  p.setKind(reset_packet_kind);
  e_stop_queue.insertPacket(&p);
 
  //idle packet: address 0xFF, data 0x00, XOR 0xFF; S 9.2 line 90
  p.setAddress(0xFF);
  p.setRepeat(10);
  p.setKind(idle_packet_kind);
  e_stop_queue.insertPacket(&p); //e_stop_queue will be empty, so no need to check if insertion was OK.
}

It's almost like the setRepeat is repeating for ever.

Short pulses are 1 and long pulses a 0,


The string of 1's is a preamble, and all 0's i believe is a reset packet. This is all I ever get.


I'm using the CmdrArduino_minimum.pde example,
Code:
/********************
* Creates a minimum DCC command station from a potentiometer connected to analog pin 0,
* and a button connected to ground on one end and digital pin 4 on the other end. See this link
* http://www.arduino.cc/en/Tutorial/AnalogInput
* The DCC waveform is output on Pin 9, and is suitable for connection to an LMD18200-based booster directly,
* or to a single-ended-to-differential driver, to connect with most other kinds of boosters.
********************/

#include <DCCPacket.h>
#include <DCCPacketQueue.h>
#include <DCCPacketScheduler.h>


DCCPacketScheduler dps;
unsigned int analog_value;
char speed_byte, old_speed = 0;
byte count = 0;
byte prev_state = 1;
byte F0 = 0;

void setup() {
  dps.setup();

  //set up button on pin 4
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH); //activate built-in pull-up resistor 
}

void loop() {
  //handle reading button, controls F0
  byte button_state = digitalRead(4); //high == not pushed; low == pushed
  if(button_state && (button_state != prev_state))
  {
    //toggle!
    F0 = (F0+1)%2;
    Serial.println(F0,BIN);
    dps.setFunctions0to4(3,F0<<4);
  }
  prev_state = button_state;

  //handle reading throttle
  analog_value = analogRead(0);
  speed_byte = (analog_value >> 2)-127; //divide by two to take a 0-1023 range number and make it 0-127 range.
  if(speed_byte != old_speed)
  {
    dps.setSpeed128(3,speed_byte);
    old_speed = speed_byte;
  }
  dps.update();
 
  ++count;
}

Any ideas guys?
Logged

UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Minor progress,

Commenting out a large portion of DCCPacketScheduler::setup(void) has got it to output new packets, but of course it no longer resets locos on power up, which isn't great...

Code:
void DCCPacketScheduler::setup(void) //for any post-constructor initialization
{
  setup_DCC_waveform_generator();
 
  //Following RP 9.2.4, begin by putting 20 reset packets and 10 idle packets on the rails.
  //use the e_stop_queue to do this, to ensure these packets go out first!
 
  DCCPacket p;
  byte data[] = {0x00};
 
  //reset packet: address 0x00, data 0x00, XOR 0x00; S 9.2 line 75
  /*p.addData(data,1);
  p.setAddress(0x00);
  p.setRepeat(20);
  p.setKind(reset_packet_kind);
  e_stop_queue.insertPacket(&p);*/
 
  //idle packet: address 0xFF, data 0x00, XOR 0xFF; S 9.2 line 90
  /*p.setAddress(0xFF);
  p.setRepeat(10);
  p.setKind(idle_packet_kind);
  e_stop_queue.insertPacket(&p); //e_stop_queue will be empty, so no need to check if insertion was OK.
  */
}


I'm thinking it's to do with setRepeat which is an inline in DCCPacket.h
Code:
inline void setRepeat(byte new_repeat) { size_repeat |= new_repeat&0x0F ;}//repeat = new_repeat; }


The search continues
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello! I'm the author of this library; I've heard tell others have had this same problem, but I can't replicate it, mostly because the problem seems to crop up on Arduino Megas, and I don't own one. Are you using a Mega?

Anyway, contact me off list if you need assistance, because I need your help tracking this bug down!

Thanks!
Logged


UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm actually running your library on a Spark Fun 328 pro mini, with a Mega sending commands over serial.

I've come across another problem, possibly related. If I send an eStop the library then seems to stop responding to further commands, need to get the scope out to see whats happening there though.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Interesting. Development was all done on a '168. Don't have a booster at the moment (waiting on the newest batch of LOLbooster PCBs to be fabbed up), so I'm not currently in a position to run the code with a real, live train (and my o'scope sucks at capturing DCC packets), but I will review both the initialization code and the estop code. The initialiation code had been working for me, but it is actually within NMRA spec to elide the layout reset bit; that's optional. So if that works for you, do it for now. The estop code is less well tested, and I have a susupicion that what's happening is in fact related.

Best guess: The estop_queue, which is used primarily for holding estop packets, but is also used by the layout reset code, is not handling packet repeats correctly, looping forever.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Think I've fixed it. Found a nasty little bug in DCCPacket::setRepeat() that would prevent it from ever being set to zero! Download the latest version of the "master" branch, and try it out.

While you're at it, would you care to try out the "mega" branch on your Arduino Mega for me?
Logged


UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

After a quick test it seems to startup just fine, allowing the loco to run, however eStop doesn't work now.
I'll do a more testing later to make sure it's not my fault.

I'll dig out the Mega from the controller and test the Mega branch too.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Apparently I never finished the e-stop code! Fixed.
Logged


UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

After a couple of tweaks it's working!

Fixed a typo - e_stop_packet.setReepat(10); to e_stop_packet.setRepeat(10);
Changed data value - byte data[] = {0x61}; to byte data[] = {0x41};

I think DCCPacketScheduler::eStop(unsigned int address) needs a tweak too
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Found a few more typos besides; all patched now; MEGA branch updated too.
Logged


UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That all seems to be working perfectly now, nicely done!

As to the Mega, a couple of issues,

first the compiler throws up:
DCCPacketScheduler.cpp: In function 'void __vector_17()':
DCCPacketScheduler.cpp:154: error: 'current_packet' cannot be used as a function

Commented out line 154 Serial.print(current_packet(j),HEX); and it compiles ok


Second is there no output on pin9 at all.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, that line should have had square brackets:

Serial.print(current_packet[j],HEX);

That's debugging code from back when I suspected the problem you were experiencing was Mega-specific. Just comment all those Serial.print lines out.

Finally, on the Mega, the DCC signal is output on digital pin 11, not pin 9. smiley-grin
Logged


North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been watching this thread with interest - nice work on this library smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been watching this thread with interest - nice work on this library smiley

Thank you! I hope to have an OpenLCB library to augment it by the NMRA West convention, to make a complete Arduino-based command station.
Logged


UK
Offline Offline
Full Member
***
Karma: 1
Posts: 131
mini mini mini
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That explains alot, with the booster hooked up to pin 11 it's working perfectly!
Logged

Pages: [1] 2   Go Up
Jump to: