Page 1 of 1
Gertbot DCC Python example
Posted: Tue Jun 30, 2015 11:08 pm
by mike21724
Very nice unit - but I am having a major mental blockage on getting it working utilizing the Python library provided. Has anyone got the basics going using pure Python? Forward, back etc, once I have that I will work the rest out.
Thanks
Re: Gertbot DCC Pyhton example
Posted: Wed Jul 01, 2015 8:17 am
by Gert van Loo
At the bottom of this page:
http://www.gertbot.com/download.html
there is a python example:
http://www.gertbot.com/gbdownload/src/py_rover.tgz
It is for two brushed motors.
Is that the one you are using?
p.s. I corrected the typo in the title to make it easier for others to find.
Re: Gertbot DCC Python example
Posted: Wed Jul 01, 2015 3:07 pm
by mike21724
I'm trying to do DCC. Used the rover to get some basics stuff going (UART etc) but now I'm up to trying to send it a DCC command and I'm not sure of the structure.
Do we send preamble, the DCC decoder address is included in the data packet etc...
Thanks
Mike
Re: Gertbot DCC Python example
Posted: Wed Jul 01, 2015 3:36 pm
by Gert van Loo
I am at work and have a better look later.
If I remember:
To send a DCC command you put all the standard DCC data in a array and send it to a board and to a channel.
Simplest is to send it to ALL channels. (Channels which are not in DCC mode will just ignore the command)
the python arguments are: send_dcc_mess(board,channel,data)
I hope you know what your board ID is set to.
For channel use 0x0F.
To send a stop command fill data with two values: the locomotive number and the stop command.
e.g. Loc = 0x03 and stop = 0x40
The 'send_dcc_mess' routine will do the rest.
Re: Gertbot DCC Python example
Posted: Thu Jul 02, 2015 5:13 pm
by Gert van Loo
Sorry, yesterday was gone before I realized it.
I have unearthed some Python code I used to test the DCC.
Code: Select all
board = 0
print("DCC test on board %d\n" % board)
for chan in range(0,4) :
gb.set_mode(board,chan,gb.MODE_DCC)
print("Performing number of writes\n")
message = [0x03, 0x68 ]
print("0x03,0x68: move loc 3. Press return to send")
input()
gb.send_dcc_mess(board,0xF,message)
message = [0x02, 0x67 ]
print("0x02,0x67: move loc 2. Press return to send")
input()
gb.send_dcc_mess(board,0xF,message)
message = [0x00, 0x40 ]
print("0x00,0x40: Stop All. Press return to send")
input()
gb.send_dcc_mess(board,0xF,message)
Re: Gertbot DCC Python example
Posted: Thu Jul 02, 2015 5:38 pm
by mike21724
Awesome thanks, I am familiar with those days.
I reread the spec last night (that's a great way to get to sleep) and I think the critical point was that each thing that you want the train to do is a separate packet. So turn light on and go x speed are different packets.
The way the spec is written, or I read it, it takes a deep dive to determine that.
I'll test today and let you know how it goes.
Mike
Re: Gertbot DCC Python example
Posted: Thu Jul 02, 2015 10:12 pm
by mike21724
Hi Gert - got it working sort of.
Here's whats happening.
Track is connected to channel 0
If I run the python code (below) - I get an error and nothing happens.
ERROR Enable 0 was negated.
Move the track to channel 1.
ERROR Enable 1 was negated.
However if I run the Raspbian gb_dcc GUI then the train gets power to it's track (so can't be a short or anything).
Then if I run the python code I get no errors and the train moves as programmed.
Any suggestions?
Code: Select all
import gertbot as gb
import curses
import time
BOARD = 0 # Which board we talk to
PHY_CHANNEL = 0 # channel for track
LOCO = 0x04
gb.open_uart(0)
#gb.set_mode(BOARD, PHY_CHANNEL, MODE)
print("DCC test on board %d\n" % BOARD)
for chan in range(0,4) :
gb.set_mode(BOARD,chan,gb.MODE_DCC)
print ("ERROR" , gb.error_string(gb.read_error_status(BOARD)))
print ("MOTOR CONFIG " , gb.get_motor_config(BOARD, 0))
print("Performing number of writes\n")
message = [0x04, 0x63 ]
print("0x04,0x68: move loc 4. Press return to send")
input()
gb.send_dcc_mess(BOARD,0xF,message)
Re: Gertbot DCC Python example
Posted: Fri Jul 03, 2015 7:35 am
by Gert van Loo
You are right!
I could not remember the details but I had a recollection that I also saw the enables activating.
I just went into the C-GUI code and found this:
Code: Select all
case MOT_MODE_DCC:
// First switch channel short circuit to off
uart_tx(CMD_STOPSHORT,id,ENDSTOP_OFF|ENB_ERR_IGNORE); // No short no endstops
// DCC mode
uart_tx(CMD_OPMODE,id,mode);
Just as a note: the short circuit protection is never switched off completely.
You just switch off that the CPU disables the channel.
I have to update the python drivers to include that.
Re: Gertbot DCC Python example
Posted: Fri Jul 03, 2015 2:55 pm
by mike21724
Thanks, I'll test and let you know.
Mike
Re: Gertbot DCC Python example
Posted: Mon Jul 06, 2015 5:51 pm
by mike21724
I added the three missing globals and then used send_raw to transmit them. I still get the "Enable 1 was negated" message but the train moves.
Code: Select all
ENB_ERR_IGNORE = 0x00
CMD_START_VAL = 0xA0 # Serial protocol start flag
CMD_STOP_VAL = 0x50 # Serial protocol end flag
print("DCC test on board %d\n" % BOARD)
for chan in range(0,4) :
message = []
gb.ENDSTOP_OFF | ENB_ERR_IGNORE, CMD_STOP_VAL)
message.append(CMD_START_VAL)
message.append(gb.CMD_STOPSHORT)
message.append((BOARD<<2) | chan)
message.append(gb.ENDSTOP_OFF | ENB_ERR_IGNORE)
message.append(CMD_STOP_VAL)
gb.send_raw(message)
gb.set_mode(BOARD,chan, gb.MODE_DCC)
Re: Gertbot DCC Python example
Posted: Fri Jul 24, 2015 5:23 pm
by mike21724
Hey Gert,
This was working and now it's stopped with a weird message:
('ERROR', 'Illegal error status code')
('MOTOR CONFIG ', [])
Dumbed down the code to minimum and still failing. Not sure what the message means:
Code: Select all
ENB_ERR_IGNORE = 0x00
CMD_START_VAL = 0xA0 # Serial protocol start flag
CMD_STOP_VAL = 0x50 # Serial protocol end flag
for chan in range(0,4) :
message = []
#gb.send_raw(gb.ENDSTOP_OFF | ENB_ERR_IGNORE, CMD_STOP_VAL)
message.append(CMD_START_VAL)
message.append(gb.CMD_STOPSHORT)
message.append((BOARD<<2) | chan)
message.append(gb.ENDSTOP_OFF | ENB_ERR_IGNORE)
message.append(CMD_STOP_VAL)
gb.send_raw(message)
gb.set_mode(BOARD,chan, gb.MODE_DCC)
print ("ERROR" , gb.error_string(gb.read_error_status(BOARD)))
print ("MOTOR CONFIG " , gb.get_motor_config(BOARD, 0))
Re: Gertbot DCC Python example
Posted: Fri Jul 24, 2015 5:46 pm
by Gert van Loo
Code: Select all
Dumbed down the code to minimum and still failing. Not sure what the message means:
Most likely an error in the driver.
I get an error number from the board "gb.read_error_status(BOARD)"
Then I look that up in set of strings. "gb.error_string(...)"
If the error number is outside the sets of strings the program will fail.
Please print out the error number only. So what is the value of "gb.read_error_status(BOARD)".
Then I can have a look in the code and see what the actual error is.
Re: Gertbot DCC Python example
Posted: Fri Jul 24, 2015 5:55 pm
by mike21724
print ("ERROR STRING" , (gb.read_error_status(BOARD)))
returns -1
Re: Gertbot DCC Python example
Posted: Fri Jul 24, 2015 9:04 pm
by Gert van Loo
OK, that suggest the gb.read_error_status call failed.
The board returned garbage or nothing at all.
See the python driver code below.
Code: Select all
#
# Return error status of board
# (zero means no pending errors)
# (-1 means read error)
def read_error_status(board):
# To do : check the arguments
dest = board<<2
wrtbuf = [PRE, CMD_GET_ERROR, dest, POST, POST, POST, POST]
os.write(filehandle,bytes(wrtbuf))
termios.tcdrain(filehandle)
ok , data = read_uart(4)
if (not ok) :
return -1
val = (data[2]<<8) | data[3]
return val
It also explains the error text you are seeing.
The gb.error_string code reports "Illegal error status code" for any code outside the expected range:
Code: Select all
...
"DCC illegal message (length)", # ERROR_DCC_MESS 0x0020
"Illegal error status code" ) # MAX_ERROR
def error_string(error_number):
if (error_number<0 or error_number>MAX_ERROR):
error_number = MAX_ERROR
return error_text[error_number]
I can't say why there is a read error.
Most likely the return data stream got out of sync.
That is: one or two bytes got lost.
I have no good solution to prevent that.
Re: Gertbot DCC Python example
Posted: Sun Jul 26, 2015 3:34 pm
by mike21724
hey Gert,
Thanks for the help. Did some hardware troubleshooting and after swapping the Pi it started working again, grrr...
Mike
Re: Gertbot DCC Python example
Posted: Tue Nov 24, 2015 7:54 pm
by mike21724
My adventure continues...
Working great so far BTW. I have now built a RESTFul API that controls the train via the GertBot.
My next question is about power.
I need to pull more than the 2.5a from the track (closer to 5-6a). Reading the docs I was a little confused as there seems to be 2 options (one untested).
Option 1 seems to be to sync the control signals and then parallel out the outputs.
Option 2. Is untested.
What would you recommend?