Help with programming VEX Pro

I am hoping someone could help me. I’m trying to figure out how to program the VEX Pro and I not sure about this:

void CQEGpioInt::SetData (unsigned int data)
Changes the state of the external digital I/O signals.

a bitmap with bit 0 (LSB) corresponding to digital signal 1 and bit 15 corresponding to digital signal 16 – used to change the state of signals configured as outputs. A 0 (zero) bit value set the corresponding I/O signal to be logic low. A 1 (one) bit value set the corresponding I/O signal to be logic high.

I know what a bitmap is, but I don’t remember how to do it. :confused:
(It’s been a while and I usually use EasyC). I tried looking on the internet, but didn’t have much luck.

Any help would be appreciated - this probably won’t be the last time that I’ll need some help. This is a whole new beginning for me.

Its telling you that for the unsigned int data, bit 0 corresponds to digital 1, bit 1 to digital 2 etc.

For example, to set digital output 3 you would send 0x0004 (binary 0000000000000100) to the SetData call. In practice you can use this in several ways, the simplest would be to keep a global variable with the current state of all the outputs. To set an output to 1, perform a bitwise OR on the current state of the port (perhaps there is a GetPort call ) with a bit set for the output you want to change. Again, lets set digital out 3 assuming that a variable called digitalPortData contains the current state.

digitalPortData |= 0x0004;
SetData( digitalPortData );

To set digital output 3 to 0 use bitwise AND with the compliment of the bit you want to change.

digitalPortdata &= 0xFFFB; // or use digitalPortdata &= (~0x0004);
SetData( digitalPortData );

You could also define a union that may look something like this.

typedef union {
    struct {
       // etc.....
     } bits;
    unsigned int data;
} digitalPort;

digitalPort  MyPort;

and then access each bit of the output word as in

MyPort.bits.digital_1 = 1;

But there can be portability problems with this, in fact I may have the order backwards here, it varies with compiler.

Edit: wiki page here

Basically, you have to assemble the bits into a number. Each port is represented by a power-of-two number, and you just add the relevant numbers together.

So, if you want to set just bits 0 and 13 (corresponding to ports 1 and 14), you would add together 2º + 2¹³. So, you could write this as:

value = 1 + 8192;

This type of thing is so common in C that there are several bit-wise operators that can be of use. You could use the left-shift operator “<<” to make the code easier to read:

value = 1<<0 + 1<<13;

Also, it is common for this type of math to use the bitwise-or operator “|” instead of normal addition. You do this so that bits don’t accidentally “carry” if you happen to have the same bit twice in the equation. For instance, 2+2=4 (which is probably not what you want), but 2|2=2 (which is probably what you wanted in bit-world).

So you could write this as:

value = 1<<0 | 1<<13;

You can further improve it by defining constants for the ports and then use the symbolic constants down in the code;

#define LIMIT1 (1<<0)
#define BUMPER (1<<13)
value = LIMIT1 | BUMPER;


  • Dean

I just wasn’t sure about the format needed.

I guess I’m still confused as to what I would put inside the ( ) and why?

Example: value= 1<<0 + 1<<13; SetData(value); or SetData(1+8192); or SetData(0x0004);

Does the “0x” at the front of the numbers represent that the number is hexadecimal?

That’s my main problem at the moment - figuring out what to put in the ( ) for all of the commands, the format, the range, and why.

all of the above would work
((1<<0)+(1<<13)) is the same as (1+8192) and is 0x2001


Order this and read several times :slight_smile: and then this

Most programmers use hexadecimal for addresses and for data values that need to land in bitfields, but decimal for quantities (though not always).

For instance, something like (0xff<<12) is pretty common, whereas (255<<0x0c) is identical but much less natural for most programmers.

I’ve also seen octal used occasionally, though that is diminishingly rare these days. I do wish ANSI C would formally adopt binary constants like 0b10101010. It would make life just a bit simpler for us embedded programmers that spend a great deal of time moving bits around.

BTW, it is pretty common to see a macro defined for the bit shift:

#define BIT(b) (1<<(b))
value = BIT(0) | BIT(13);

This kind of thing starts to break down when you get more complex bitfields where combinations of bits needs to be set together as a unit. That is where the use of struct (as jpearman showed) really starts to pay off. If the field get too complicated (disjoint, or spread across multiple registers) then you are going to want to write accessor functions that do nothing but get and set the bitfield.


  • Dean

Thanks for the links. I do have a book on C programming - I think I’ll being needing it now.

That would make it a lot easier!

Here’s the program I wrote to turn digital port 1 on and off 5 times and then play a tone. Would you mind looking it over for me. Is there anything that I need to know to run it - i.e. steps to follow?

[LEFT]#include “qegpioint.h”
#include “qeaudio.h”[/LEFT]

[LEFT]int main(void)
int count = 0;
int d = 0;[/LEFT]

[LEFT]// get io reference
CQEGpioInt &io = CQEGpioInt::GetRef();[/LEFT]

[LEFT]// get audio reference
CQEAudioController &audio = CQEAudioController::GetRef(); [/LEFT]

[LEFT]// set digital pin 1 to output
io.SetDataDirection(1 << 0);[/LEFT]

[LEFT]// set speaker volume


[LEFT]while(count < 6)
for (d = 0; d < 2000; d++);
for (d = 0; d < 1500; d++);
count = count + 1;

The code should work, a couple of points.

If using functions like printf you should include the standard IO header.
#include <stdio.h>

Using for loops for delays is necessary sometimes but I would try and avoid it if you can, I would guess that

for (d = 0; d < 2000; d++)

will not be enough delay anyway, look into functions like usleep as an alternative.

Obviously googling things like “c programming language ebook” may turn up some interesting reading in addition to the book you already have. There’s lots of information about C programming on the internet including some interesting historical articles by Dennis Ritchie on his home page (which unfortuinately seems to be down today).

I’ve been playing around with timing on the VEXpro, mostly in an effort to get I²C working reliably, and here are a few things worth noting:

usleep() and nanosleep() both have a 10ms resolution. That means whatever sleep you ask for, it will be rounded up to the next 10ms interval. Ask for 1ns or 1µs and you will get 10ms. Ask for 11ms and you will get 20ms.

A while() loop on a volatile long int takes around 68µs per 1000 iterations, though due to interrupts it can take much longer. I’ve seen it take over 500µs.

gettimeofday() provides microsecond resolution. I’ve defined my own microsleep() function that loops calling gettimeofday() until the requested number of microseconds have passed. Calling gettimeofday() costs around 3µs (on average).

I’m still experimenting with some of the other timer functions, as well as reading a free-running timer directly from the chipset (I want to get sub-microsecond timing so I can get I²C to perform well).


  • Dean

Thank you both for all of the tips and advice, I really do appreciate it.
You both know a lot more about robotics than I do and I’m really glad you were willing to help me out. I may need your help again later.

I searched the internet, looked at the example programs, and looked at the information here on the VEX website. I was trying to figure out as much a I could by myself, but I needed a little help.

I found a really good 200 some page PDF file on the internet covering C programming and it has helped a lot. I just used the “for” loop because the “wait” command didn’t work and I had seen it used in one of the examples. I will try the usleep function instead.

Thanks for looking my program over for me. I’m starting to get some of the concepts now and as I get some experience, hopefully I will have more confidence in my programming abilties.

I was hoping to receive my VEX Pro today, but because of the Thanksgiving holiday - the ground packages were delayed in order to deliver Overnight and 2nd Day packages. I should get it on Monday though and I can’t wait to try my program out - hopefully it will work fine and I can start trying out some more features.

Honestly though, I’m a little bit afraid that it’s not going to work.

You are very welcome.

I can’t speak for Dean, but I only know more because I’m probably a lot older than you are. I’m happy to help because the future is in your hands :slight_smile:

You’re a lucky guy, I have a cortex but it’s hard to justify a VEXpro as it has no direct application for the high school teams I help with.

Don’t stress, it’s going to be fine. If it wasn’t hard then it wouldn’t be worthwhile doing.

Thanks for the words of encouragement!

I wasn’t sure if I should get the Cortex or the VEX Pro. Besides the cheaper cost, the Cortex uses EasyC V4 which I know a lot better. Mainly, I decided to buy the Pro because of the ability to control a robot over the internet and that it has the sound functions already built in. Plus, it talks! I don’t know when they will add the sound functions for the Cortex.

Would you mind answering one more question - what library should I include for sleep and/or usleep? I’ve been looking on the internet, but I came up with conflicting answers.

usleep is normally part of the standard library (well it is on other unix systems) called libc (or glibc for the GNU version), it is probably linked for you by default. It’s disappointing to hear usleep only has 10mS resolution.

As Dean has a VEXpro perhaps he can tell us which version of linux it is running and whether man pages and things like that are installed on it.

In the meantime, here is a link to a linux man page for usleep to give you some idea.

I can confirm that this is the case. I built a timer test program, and both usleep() and nanosleep() have a 10mS resolution. gettimeofday() will report time with microsecond resolution, but costs about 3µS to call.

The EP9302 chipset has four timers. TIMER1 appears to be used by the OS for the 100Hz lbolt clock. TIMER2 and TIMER3 appear to be unused, but have a resolution of no better than about 2µS (508KHz). TIMER4 is a free-running 40-bit timer that runs at about 983KHz, so I used that for a polled-wait function with approximately 1µS resolution.

uname reports “Linux”. I’ve posted a full log of the boot sequence, as well as a list of all installed files for your perusal. No man pages are installed on the VEXpro itself, though there may be man pages installed with the TerkIDE - I’m still finding my way around Eclipse, and so far I’ve just searched the headers to find stuff.


  • Dean

Hi, I just wanted to post an update to let you how I am doing.

I did receive my VEX Pro Monday and I spent most of the night trying to get everything set up. After a few glitches and if all else fails - reading the instructions - I finally got everything working right before my battery died.

I charged 2 batteries and spent a few hours last night testing things out. After I got going, I realized as you said that it wasn’t as bad as I feared it would be. I started with a simple program to flash a couple of LEDs and kept expanding it.

So far I have:

Cleared and Printed to the LCD
Made it talk
Blinked 2 LEDs on the digital port
Ran a 2 wire motor forward and reverse

I think now I could write a program for a VEX robot. I still have much more to learn though. For example - I just copied a few of the motor command values from one of the sample programs because I didn’t know what values to put in.

One thing that is a little disappointing is that the speach didn’t sound as clear as I hoped it would. I will have to try it when the TV isn’t on though just to be sure.

I was worried about buying the VEX Pro because I usually just use EasyC and my C programming skills are limited. Now, I think I’m happy with my decesion especially after my success so far.

Thanks again for all of you help and support!