Reading and transmitting accelerometer values

I bought the Wixel to replace an Arduino/xbee configuration, but the programming seems very different. I am having trouble writing a simple program that reads and displays accelerometer values from the Memsic 2125 accelerometer. I eventually want to be able to transmit accelerometer values between two Wixels. I looked at the Wixel wireless serial app but it’s too confusing for me to figure out how to modify it to transmit accelerometer values. Any help would be very appreciated :mrgreen:

Hello, sheepcounter.

Have you found the documentation of the Wixel SDK online?
pololu.github.com/wixel-sdk/
It explains all the external libraries/functions that the wireless serial app uses. What would be most relevant to you is the documentation of the radio_com library, which lets you send bytes wirelessly between two Wixels. Or you could use the lower-level radio_link library which gives you more control over the packets that are sent but can be more difficult to use.

The tasks your code has to take care of are:

  1. Measure the accelerometer values.
  2. Decide how often to transmit reports of the accelerometer values (e.g. every 50 ms).
  3. Sends these reports when needed. In your main loop, you should call a function that would check to see if it is time to send a report AND if there is buffer space available in the radio_com TX buffers. If both of these conditions is true, then it would send the report using radioComTx* functions. Several of our apps and libraries demonstrate how to perform a task periodically; e.g. the example_blink_led app toggles an LED periodically.

Step 1 might be the hardest for you. The Memsic 2125’s output is a 100 Hz PWM signal. We don’t have any libraries available for measuring pulse widths on the Wixel, but you might be able to use Timer 1’s capture feature to do it if you read the CC2511 datasheet. Alternatively, you could get one of the accelerometer boards we sell that has an analog or I2C output. The Wixel already has libraries for doing analog and I2C communication. Analog would be the easiest choice in terms of coding because you just need to call one function (analogRead) to read the output.

Let me know if you need further help with any of these steps.

–David

Thank you so much for the assistance. I decided to get analog accelerometers to make the program simpler. In which library is the analogRead function?

Oops, the name of the function is actually adcRead and it is in the Wixel’s adc library:
pololu.github.com/wixel-sdk/adc_8h.html

–David

I installed the Wixel Windows Drivers and Software and I’m using Eclipse. I want to use printf statements to print accelerometer values, but the stdio.h library is not being recognized and the #include <stdio.h> line is highlighted.
Would the printf statements of the accelerometer values require the use of a terminal program like Putty?
Thanks

Hello,

You need to implement the putchar() function in your program for printf to work. To print to the virtual COM port, this can be as simple as calling usbComTxSendByte():

void putchar(char c)
{
    usbComTxSendByte(c);
}

You can see the source for the radio_sniffer app for an example of printf being used in this way, and yes, you would use PuTTY or another terminal program to connect to the virtual COM port and view the output.

Sometimes Eclipse will flag the “#include <stdio.h>” line simply because it does not know where stdio.h is, but the app will still compile fine because SDCC knows where it is. If the “error” indicated by Eclipse bothers you, I think you can fix this by adding the SDCC include directory to Eclipse’s include path; to do this:

  1. go to Project > Properties
  2. expand C/C++ General on the left and select Paths and Symbols
  3. in the Includes tab, under Languages, select GNU C (it might be the only option there)
  4. click the Add… button on the right and add the include directory in your SDCC installation; by default, this should be C:\Program Files (x86)\SDCC\include in 64-bit Windows or C:\Program Files\SDCC\include in 32-bit Windows (You can use the File system… button in the Add dialog to browse for the folder.)

When you are done, it should look like the screenshot below.


- Kevin

I’m still having trouble getting this to work. The radio sniffer program is confusing to me. I used Putty with the COM port listed in the Wixel configuration utility. This was my attempt:

#include <wixel.h>
#include <usb.h>
#include <usb_com.h>
#include <adc.h>
#include <stdio.h>

uint16 avalue;


void readaccel()
{


	avalue = adcRead(0 | ADC_REFERENCE_INTERNAL);  // Measures voltage on P0_0


}

void putchar(avalue)
{
    usbComTxSendByte(avalue);
}


void main()
{
    systemInit();
    usbInit();

    while(1)
    {
        boardService();
        readaccel();
        putchar();
        printf(avalue);
        usbComService();
    }
}

I copied the example blink LED app folder and renamed it “robot_project” and renamed the c file “accelerometer_test.c” and compiled it. The wixel app file still has the example blink LED name. I’m not sure if this is correct so I attached the image of the project explorer window. Also how do you set the parameters that are shown in the Wixel configuration utility? I don’t see baud rate. It still shows the LED program’s parameter.

I’d change your printf statement to

printf("adc: %d\n", avalue);

you need the format string so it knows what to do
“\n” means new line

also
remove the putchar from your main loop - not needed!

finally change your adcRead to

avalue = adcRead(0);

IMHO YMMV!

mmcp42’s suggestions are good. Your printf statement won’t work at all the way you have it currently and its good to just read P0_0 with VDD as the reference for now until you get things working. You should remove your call putchar() with no arguments (that should be a compiler error because you supplied no arguments). Also you are overlooking one very important thing about usbComTxSendByte: please read the documentation of usbComTxSendByte and/or look more carefully at the example apps:
pololu.github.com/wixel-sdk/usb_ … 348f4eb8c1

It looks like you are having trouble compiling and Eclipse is showing you old files that don’t exist any more. You said you renamed example_blink_led.c so why do we see that in the list? You can try pressing F5 to refresh Eclipse’s view. Please try this: run “make clean”, remove all files from your app directory except accelerometer_test.c, then run “make”. That should compile apps/robot_project/robot_project.wxl. Please inspect the directory using Windows Explorer, not Eclipse, because the list of files displayed by Eclipse can be out of date.

–David

Thank you for the suggestions. It gives me an error after I compile that says there are two or more data types in the putchar declaration. I’m not sure what’s wrong. This is my code:

#include <wixel.h>
#include <usb.h>
#include <usb_com.h>
#include <adc.h>
#include <stdio.h>

uint16 avalue;


void readaccel()
{


	avalue = adcRead(0);  // Measures voltage on P0_0


}

void putchar(avalue)
{

	  if(usbComTxAvailable() >= 128){
    usbComTxSendByte(avalue);

	  }
}


void main()
{
    systemInit();
    usbInit();

    while(1)
    {
        boardService();
        readaccel();
        printf("adc: %d\n",avalue);
        usbComService();
    }
}

I put “putchar(‘avalue’)” after readaccel() and it still didn’t work. If putchar isn’t needed in Main, I don’t understand how it’s used.

ah
couple of things I would change
a) instead of using avalue as a global, change your readaccel function to return a value:

uint16 readaccel(void)
{
  return adcread(0);
}

b) your putchar routine is looking for at least 128 bytes of buffer before it does anything
you only need 1 as I understand it!

also you need to decalre the type of avalue as char
so

void putchar(char avalue)
{
  if (usbComTxAvailable()>0)
    usbComTxSendByte(avalue);
}

should be fine

the way putchar works is
you call printf
it calls putchar
so you don’t explicitly call it

can you show the compile error you get…

Thank you, I followed your suggestions. However I’m still getting an error:

and an app file isn’t created after I “Build All”.

yeah I get that sometimes
fix seems to be to delete all the “odds and sods” files (xxx.d, xxx.a etc)
i.e. anything that isn’t xxx.c!
then try again

Hello, sheepcounter.

Could you please type make -v in a Command Prompt and post the output here?

–David

This is the output after typing “make -v”:

After deleting the .adb and .d files and compiling again, an app file was created. I wrote it to the Wixel using the configuration utility. I used Putty to see the output which should have shown accelerometer data. Nothing appeared. I tried building again and got the “make: Interrupt/Exception caught (code = 0xc0000005, addr = 0x0x416638)” message again (not sure if that was supposed to happen).

The “Interrupt/Exception caught” message from make is definitely an error. I would like to work with you and mmcp42 to debug it create a new version of make, but you would probably prefer to get your actual application working first, so let’s do that. Please post your entire Wixel app code here again so we can see if there are any remaining bugs.

For now, as a workaround to the bug in make, try compiling your app by typing one of the commands (whichever one doesn’t crash):

make clean robot_project
make clean && make robot_project

I recommend using make to load the app on to your Wixel because it will be much faster than the Wixel Configuration Utility. You can compile and load in two keystrokes using the Up Arrow at the command prompt, which goes to your last command. The command for that would be “make clean load_robot_project” or “make clean && make load_robot_project”.

–David

thanks David
I have made a note of the instructions
next time it happens I’ll follow and report :slight_smile:

Thank you. This is the code:

#include <wixel.h>
#include <usb.h>
#include <usb_com.h>
#include <adc.h>
#include <stdio.h>

uint16 avalue;

uint16 readaccel(void)
{

	return adcRead(0);  // Measures voltage on P0_0

}

void putchar(char avalue)
{

	  if(usbComTxAvailable() >= 1)
    usbComTxSendByte(avalue);


}


void main()
{
    systemInit();
    usbInit();

    while(1)
    {
        boardService();
        readaccel();
        printf("adc: %d\n",avalue);
        usbComService();
    }
}

I tried both “make clean load_robot_project” and “make clean && make load_robot_project” in the command prompt and got the message “No rule to make target ‘clean’. Stop.”

you need

avalue = readaccel();

cheers
Mike

I just tried that and I’m still not getting anything output in the Putty terminal window…in Putty the baud rate is set to 9600. I’m not sure if this could be the problem and how I would find the correct baud rate.

Thanks!