Page 1 of 1

Gertbot GPIO pins

Posted: Mon Jan 12, 2015 11:37 am
by donnyo
My Gertbot robot is working well with motors and the excellent low latency mjpg streamer via Python but I'm really stuck on how to set the J3 GPIO Pins in Python and wonder if some kind soul might please help.

I'm fine with ordinary Raspi GPIO control but am really stuck with doing the same on the Gertbot using its set_pin_mode and set_output_pin_state. Had assumed setting board 0 pin 13 mode to output would be as simple as

Code: Select all

gertbot.set_pin_mode(0,13,PIN_OUTPUT) 
but it doesn't like my PIN_OUTPUT. Can anyone familiar with Gertbot pin control post an example of how to set and then flip OUTPUT on and off in Python please? I've read the manuals and python drivers but still can't see and i get lost in the .c. and .h files. An official python Pin control code example would really help please, if Gert watches the forum!

Re: Gertbot GPIO pins

Posted: Mon Jan 12, 2015 4:11 pm
by Gert van Loo
donnyo wrote:My Gertbot robot is working well with motors and the excellent low latency mjpg streamer via Python but I'm really stuck on how to set the J3 GPIO Pins in Python and wonder if some kind soul might please help.

I'm fine with ordinary Raspi GPIO control but am really stuck with doing the same on the Gertbot using its set_pin_mode and set_output_pin_state. Had assumed setting board 0 pin 13 mode to output would be as simple as

Code: Select all

gertbot.set_pin_mode(0,13,PIN_OUTPUT) 
but it doesn't like my PIN_OUTPUT. Can anyone familiar with Gertbot pin control post an example of how to set and then flip OUTPUT on and off in Python please? I've read the manuals and python drivers but still can't see and i get lost in the .c. and .h files. An official python Pin control code example would really help please, if Gert watches the forum!
Gert watches the forum but on irregular time intervals.

try gertbot.PIN_OUTPUT

Re: Gertbot GPIO pins

Posted: Mon Jan 12, 2015 7:16 pm
by Gert van Loo
Just for reference you find attached the python code I used to verify the drivers.
This was not written for official release so you will not find a lot of comment
as to me the code is self explanatory, but it does show example usages of every function.

Re: Gertbot GPIO pins

Posted: Wed Jan 14, 2015 11:11 am
by donnyo
Many thanks Gert. This helps.

I'm scratching my head though on a few points though:

CMD_ENDSTOP seems not to be defined in gertbot.py driver so Test 9 and 10 for example crash with:
Test set J3 pin mode in board 0
Going to switch pins 1-10 to output (press return)
……
Going to switch pins 1-8 to endstop (press return)

Traceback (most recent call last):
File "test_drivers.py", line 772, in <module>
if test==9 : test_set_pin_mode() # 1/10/14 passed
File "test_drivers.py", line 386, in test_set_pin_mode
gb.set_pin_mode(board,i,gb.PIN_ENDSTOP)
File "/home/pi/Downloads/Drivers/gertbot.py", line 665, in set_pin_mode
wrtbuf = [PRE, CMD_ENDSTOP, id, endstop,POST]
NameError: global name 'CMD_ENDSTOP' is not defined
Secondly I've determined that the pin numbering is not as I had expected:
The Gertbot GUI document and GUI show Pin numbers 1 to 10 for the IO and Endstop pins and starting at top left if the pin block were vertical so:
1 2
3 4
5 6
7 8
9 10
However, using python,

Code: Select all

gb.set_pin_mode(board,1,gb.PIN_OUTPUT)
in fact controls the top right pin labelled pin2( also labelled Ext.0)
so the actual Pin numbering is instead
2 1
4 3
6 5
8 7
10 8
..this seems not consistent with GUI, manual or the pin order I expected and really threw me!

ADC pins are 13-16 but laid in order
14 13
16 15

Could you please clarify the Pin numbering and if this is intended.
What has me further scratching my head is given this pin numbering why DAC0 and DAC1 ( which are numbered 18 and 20 on GUI) and I would expect to be numbered 17 and 19 won't change mode using:

Code: Select all

gb.set_pin_mode(board,17,gb.PIN_OUTPUT)


Oh and running test 3 I get:
Running test 3

Test move brush mode on board 0
Traceback (most recent call last):
File "test_drivers.py", line 766, in <module>
if test==3 : test_move_brushed() # 1/10/14 passed chan 0 & 2
File "test_drivers.py", line 175, in test_move_brushed
gb.move_brushed(board,channel,1,4)
TypeError: move_brushed() takes exactly 3 positional arguments (4 given)
The Gertbot runs our robot modelled on NASA's Mars Rover Curiosity, based on a DIddyborg chassis, powered by 12V Lipo regulated down to 9v for the motor controller which run the 4x6V motors and the same 12V Lipo has a Dc-DC controller for the 5V for Gertbot and RPi.
We stream low latency video using excellent mjpg streamer and use the IO pins to power bright LED spotlights to navigate in the dark. We will add a Mearm and attach a drill bit to a motor for a pseudo drill like the real rover! Nice that you leave some of the RPi GPIOs free to be used too.

Will your code be on gitgub or one of the offical repositories soon rather than just the gertbot website if drivers update for example? I think the test_drivers.py is a useful addition by the way!

huge thanks in advance.

Re: Gertbot GPIO pins

Posted: Wed Jan 14, 2015 11:12 pm
by Gert van Loo
Donnyo,
I will look into it all but at the moment I have no access to a development set-up
nor to any test equipment. I looks like it will be a few weeks before that
is resolved so I am afraid it may take me a while to come back to you.

I know that I made some last minute changes to the drivers and they where
not tested with that program.
Also it took me a looong to get the I/O working. In fact it took me longer
to implement the various I/O modes than the stepper motor code!

At the moment I do not have the code on Github but I will think about that.
It is just that I have started a new job on the 5'th of January so I am a bit busy.

Re: Gertbot GPIO pins

Posted: Thu Jan 15, 2015 5:26 pm
by donnyo
Thx Gert,
I can workaround for time being and imagine others will come across this. What's the best way to communicate features if I find them...open forum or PM?
Am happy to provide as much feedback as is helpful.

Re: Gertbot GPIO pins

Posted: Fri Jan 16, 2015 8:15 am
by Gert van Loo
Open forum is best.
Are you using stepper motors?
I recently found an error in the stepper driver and I am preparing a new image to upload.

Re: Gertbot GPIO pins

Posted: Fri Jan 16, 2015 1:37 pm
by donnyo
Hi Gert,

Re GPIO numbering- for sure the numbering in GUI (+manual) and in python test_drivers.py and gertbot.py driver code are inconsistent but my limited reading suggests that in fact the Raspi numbering might in fact break with tradition by using a:

1 2 | <-edge of board
3 4 | <-edge of board
5 6 | <-edge of board
7 8 | <-edge of board

… numbering scheme but is it not more conventional in non-Raspi IOs to have odd numbers at edge of board (as you have them) so in case of J3 connectors:

2 1 | <-edge of board
4 3 | "
6 5 | "
8 7 | "

I understand the board can be used without a Raspi so anyone not used to Raspi GPIO numbers would not be so concerned!
In this case your numbering is then understandable. Perhaps could you amend GUI labels and documentation and gertbot.py and test_drivers.py which refer to Pin numbers inconsistently too, sometimes 1 to 20 and other times 0 to 19. As long as they all refer to the same thing!

I’m interested too in why board boots with IO pins 1-10 (or 0 to 9!) as Inputs (safer I would assume), yet I still measure 3v3 coming from them in this default state, with enough current to make a connected LED glow dimly. When I turn pins to Output and state Low, LEDs don’t light up which is the way Raspi GPIO pins work too. So exitting from gertbot code means any connected LEDs continue to glow dimly whereas I'd prefer I think all pins to be like the Raspi GPIOs = off totally unless allocated a mode & state.

Can I please ask how to control the state of individual Output Pins in Python rather than all of them and why I can't see all pins state change?

Code: Select all

set_output_pin_state(board,output)
does not take a Pin argument which I would have expected to see to control multiple output pins. The driver comment says it controls all pins. Can we please have as well a way to change individual Pin states as the GUI can do this and so the board clearly can. Is this just something not yet implemented in Python but easily do-able?

Code: Select all

import gertbot as gb
gb.set_pin_mode(0,1,gb.PIN_OUTPUT)    # Pin 1 Ext.0)
gb.set_pin_mode(0,2,gb.PIN_OUTPUT)    # Pin2 Ext.1
gb.set_output_pin_state(0,1)
..in my case only turns the first output Pin(board 0 pin0,1) High. I would expect from the driver that all output pins would be set to high too but this does not appear to me the case. In any case, I’d still ask please for how to change output status pin by pin !
I’m struggling to get my head around the raw commands but would a workaround be to use:

Code: Select all

def send_raw(arg):
os.write(filehandle,bytes(arg))
Can you please give an example of setting 2 pins to OUTPUT then HIGH and then back to LOW using python and send_raw arguments as a workaround!? I Just can't get my head around the raw commands in the GUI log.

Huge thanks,

Re: Gertbot GPIO pins

Posted: Fri Jan 16, 2015 2:17 pm
by Gert van Loo
I’m interested too in why board boots with IO pins 1-10 (or 0 to 9!) as Inputs (safer I would assume), yet I still measure 3v3 coming from them in this default state, with enough current to make a connected LED glow dimly
Because, as the manual states: they have 4.7K pull-ups.
That makes it easier to make end-stops: the user only has to add a switch.
More usual are pull-up value in the range of 20k-47K, but in a 'motor' environment I decided for a bit more pull as it is less susceptible to noise.
Therefore you see the LEDs "glow" more then with other boards.
When I turn pins to Output and state Low, LEDs don’t light up which is the way Raspi GPIO pins work too.
As to LED ON or OFF when you set your bit high/low: that depends on how you connect your LEDs.
LED+R between VCC and PIN: you get the inverse mode: pin high is LED off.
LED+R between PIN and GND: you get the true mode: pin high is LED on.
Can we please have as well a way to change individual Pin states as the GUI can do this and so the board clearly can
In fact: the GUI does not control individual pins. It 'remembers' the state of all pins and AND-es or OR-es the new pin into it.
Assume 'pin_state' holds the high or low state of all output pins.
Then to set a pin X high:
pin_state |= (1<<X);
gb.set_output_pin_state(0,pin_state)
To set pin X low:
pin_state &= ~(1<<X);
gb.set_output_pin_state(0,pin_state)
The exor operator '^' can be used to toggle to the reverse state:
pinstate ^= (1<<X);

This is code taken from the 'toast-e' control program.
It is written in C but has the same and-or structure.
The 'pin_state' is here named 'mouth' the ')' command toggels the 'mouth' state on and off.
I first read the bit and check if it is on or off. Then I change it to the opposite value.
The exor operator '^' can be used for pure toggle_to_reverse_state control.

Code: Select all

      case ')' : // Smile on/off
                 if (mouth & MOUTH_SMILE_BIT)
                 { // is on: switch off
                   mouth &= ~MOUTH_SMILE_BIT;
                 }
                 else
                 { // set smile on requires middle on too
                   mouth |= (MOUTH_SMILE_BIT | MOUTH_MIDLE_BIT);
                   // disable potential frown
                   mouth &= ~MOUTH_FROWN_BIT;
                 }
                 set_output_pin_state(BOARD,mouth);
I Just can't get my head around the raw commands in the GUI log
Beware that send_raw was never ment to be used other then in extreme cases.
I only use it to send commands which are WRONG so I can check if the error detect system works.
It sends the bytes AS-IS to the board thus you must make sure the command is preceded by the start-command byte and finished with one or more end-command bytes
and that it has the exact right number of bytes. If the latter is wrong it may confuse the internal FSM so that your next command is lost as well.
In order to understand the raw commands in the GUI log you have to read the command section of the maual. The drivers are there so you don't have to. ;)
The log RAW commands are usefull for replaying command so you can use the board without having to know anything about programming!
(See https://www.youtube.com/watch?v=_UTNJ79 ... e=youtu.be)

Re: Gertbot GPIO pins

Posted: Fri Jan 16, 2015 2:32 pm
by donnyo
Thanks Gert for such a quick response. Three cheers for Toaste's mouth gestures. Will have a play.

Re: Gertbot GPIO pins

Posted: Thu Feb 05, 2015 10:28 am
by donnyo
Hi Gertbot users,

Wonder if someone can help me please to control Gertbot opendrain and IO pins independently:

Using Gerbot I can control the IO pins just fine with bitwise. That's now clear to me. I then got opendrain working to turn on and off some 3W, 700 mA superbright LEDs but I just can’t understand quite why turning Gertbot IO pins low should also deactivate the open drains.

Code: Select all

…
pin_state= 0
pins_needed = [1,2,3] # NB 1= Ext.0,2= Ext.1, 3= Ext.2 etc
for pin in pins_needed:
    gb.set_pin_mode(0,pin,gb.PIN_OUTPUT)
…
if key==ord(‘l’) :    # turns LED spotlights On
    pin_state |=(1<<0);    # enable / go high pin Ext.0
    pin_state |=(1<<1);    # “                pin Ext.1
    pin_state |=(1<<2);    # “                pin Ext.2
    d0 = 1 & 1;    # 1 & 1 to enable D0
    d1 = (1 & 2)>>1;    # (1 & 2) to enable d1
    gb.set_output_pin_state(0,pin_state)
    gb.activate_opendrain(0,d0,d1)   #enables OD0

if key==ord('o') :    # turn LED spotlights Off
    pin_state &=~(1<<0);  # pin 0 Ext. 0 
    pin_state &=~(1<<1);  # pin 1 Ext.1
    pin_state &=~(1<<2);  # pin 2 Ext.2
    gb.set_output_pin_state(0,pin_state)
If I then comment out the IO pin state code and use gb.activate_opendrain then this works in deactivating the opendrain :

Code: Select all

if key==ord('o') :    # turn LED spotlights Off
    #pin_state &=~(1<<0);  # pin 0 Ext. 0 
    #pin_state &=~(1<<1);  # pin 1 Ext.1
    #pin_state &=~(1<<2);  # pin 2 Ext.2
    #gb.set_output_pin_state(0,pin_state)
     d0 = 0 & 1;    # 0 & 1 to turn off OD0
     d1 = (0 & 2)>>1;    # (0 & 2)..1; to turn off OD0
     gb.activate_opendrain(0,d0,d1)
.
What I'm really struggling with is understanding why gb.set_output_pin_state impacts opendrains as I would expected to have to use only gb.activate.opendrain(..) to control the opendrains. Does pin_state actually contain more than the state of pins 0-19? Many thanks in advance.

Re: Gertbot GPIO pins

Posted: Thu Feb 05, 2015 5:08 pm
by Gert van Loo
I'll have a look at the SW. It may be a real bug. If so I will push out a new image ASAP.

-- Gert

Re: Gertbot GPIO pins

Posted: Thu Feb 05, 2015 5:48 pm
by donnyo
Many thanks. If I can help with any release candidate code and associated documentation I gladly will; just PM me. It's a great, powerful board that does so much. I'd like to help to make the Python example and documentation a bit clearer so every user can get the most from it out of the box, as it deserves, if you'd like a few suggestions.

Re: Gertbot GPIO pins

Posted: Thu Feb 05, 2015 8:22 pm
by Gert van Loo
Yep, found it. When setting the outputs I also touch the open-drain status bits. (They are always set to zero, disabling the opendrains)
Working on a solution but I have no access to equipment to test this.
I will try post now code on Saturday.
That also fixes the "first step wrong on stepper-motor" 2 bug.

For now the only solution I see is that you have to re-send the open-drain command after setting the outputs.

Re: Gertbot GPIO pins

Posted: Fri Feb 06, 2015 6:08 pm
by Gert van Loo
While I am updating the code I am adding a 'set baud rate' command.
case 0 : 19200
case 1 : 38400
case 2 : 57600
case 3 : 115200
case 4 : 230400
I can't guarantee it all works fine in case 3 let alone 4 but at least you can try.

The two lower baud rates are 'just because I can'
The are not useful in a noisy environment as you first have to send the command at the default 57600 rate which may not work.
But I bet there will be at least one hacker repeatedly re-trying until it works....
Any other urgent requests which are not too difficult to add?

Re: Gertbot GPIO pins

Posted: Sun Apr 26, 2015 10:26 pm
by Gert van Loo
Software revision 2.6 is out
That DOES fix the open collector issue as I now have the equipment to test it.
Version 2.6 also supports quadrature encoders and the Gertbot has a whole set of
new commands to use.

For some (yet unknown) reason Baud rates 19K and 230K do not work with the PI.
They DO work with a windows machine and a FTDI USB converter which suggest
a rate discrepancy between the Pi and the gertbot.

Re: Gertbot GPIO pins

Posted: Thu Apr 30, 2015 8:04 pm
by donnyo
Many thx - am just waiting for a replacement 12v Lipo battery as my last Chinese ebay one gave up the ghost and then I can play with the new drivers and firmware, so Gertrude our Loo-nar rover will roam again!

Re: Gertbot GPIO pins

Posted: Tue Sep 01, 2015 2:43 pm
by moriss
After all the explanations and the fact that Donnyo apparently has gotten the grasp of things (in conversational mode), the whole J3 question is still a great enigma to me.
a. It is absolutely unclear which pin is to be called by what number and what its function is or can be, and in what combinations.
b. It is absolutely unclear whether the pins are set as a byte/halfword group by AND-ing and OR-ing against a mask, or that they can be individually set and read.
c. There is no description of the 20 pins (in three groups of eight !!)
d. What we really need is a picture and mnemonic names and clear descriptions.

Please write a manual.

I broke my Gertbot trying to find out, and I'm not buying a new one until there is a decent manual.
It says "READ THE MANUAL". Well, the manual is clear, but only for trivial operations. For the more interesting stuff it is obscure.

Re: Gertbot GPIO pins

Posted: Wed Sep 02, 2015 12:49 pm
by Gert van Loo
moriss wrote:After all the explanations and the fact that Donnyo apparently has gotten the grasp of things (in conversational mode), the whole J3 question is still a great enigma to me.
a. It is absolutely unclear which pin is to be called by what number and what its function is or can be, and in what combinations.
b. It is absolutely unclear whether the pins are set as a byte/halfword group by AND-ing and OR-ing against a mask, or that they can be individually set and read.
c. There is no description of the 20 pins (in three groups of eight !!)
d. What we really need is a picture and mnemonic names and clear descriptions.

Please write a manual.

I broke my Gertbot trying to find out, and I'm not buying a new one until there is a decent manual.
It says "READ THE MANUAL". Well, the manual is clear, but only for trivial operations. For the more interesting stuff it is obscure.
I am sorry you feel that way. I would like to start with pointing out that there is no other add-on board for the Raspberry-Pi which comes with a manual as extensive as the Gertboard. Many of them have only one or two pages.
As to your other remarks: most of your questions are answered by the BCM2835 datasheet, which by the way I also wrote.
That includes subjects like: "Which pin is to be called by what number and what its function is or can be, and in what combinations"
That datasheet also also covers: "It is absolutely unclear whether the pins are set as a byte/halfword group by AND-ing and OR-ing against a mask, or that they can be individually set and read."

As to "There is no description of the 20 pins (in three groups of eight !!)". With that sentence you have just shown how difficult it is to accurately describe hardware into words. What 20 pins are you talking about? What are the three groups of eight? Three times eight makes 24 so I can't match that against your number of twenty. I know that may seem childish but I am trying to bring home the point.

"What we really need is a picture and mnemonic names and clear descriptions"
I object against the word 'we'. I think the term "I" is more appropriate.
The board has been on the market for two years and users managed perfectly with what there is.
It seem to me you want a lot more guidance and step-by-step details. Whoever there is only so much guidance
possible after which the user is expected to start to see the pattern and take it from there.
As I said: I am sorry that did not happen with you.

Re: Gertbot GPIO pins

Posted: Sun Nov 01, 2015 1:16 pm
by BIGherman
I have spent a few frustrating hours chasing around between code, hardware and documentation (read: forum posts, such as this thread), trying to figure out how to set individual J3 pins for output on the Gertbot.
I think I've cracked it and so, I thought it might be worth posting an addition that I've made to the "official" gertbot.py download, to provide a function for setting individual pins for output. My comments in the code also include what I understand to be the pin layout on J3...
I would welcome any feedback, as I give no guarantee that my experimentation has been 100% successful ;)

Code: Select all

#
# Provides a function to toggle the state of individual GPIO (J3) pins
# Pin 1 is referenced by position 0 in the gpio_output_states variable
# and so on : as per the comments above set_output_pin_state
#
# Global variable gpio_output_states is set to 0x0000 on module load
# PIN_LOW = 0, PIN_HIGH = 1 set on module load
#
# Board setup:
# J3 etching on board
# 19 20 <-Edge
# 17 18 <- "
# 15 16 <- "
# 13 14 <- "
# 11 12 <- "
#  9 10 <- "
#  7  8 <- "
#  5  6 <- "
#  3  4 <- "
#  1  2 <- "
 
def set_single_pin_state(board,pin,state) :
   global gpio_output_states

   # Use standard bitwise operators to set and unset bits
   if state==PIN_HIGH:
      gpio_output_states |= 1<<(pin-1)
   elif state==PIN_LOW:
      gpio_output_states &= ~(1<<(pin-1))

   set_output_pin_state(board,gpio_output_states)