Raspberry Rower

From Hamsterworks Wiki!

Jump to: navigation, search

I'm going to make my Raspberry Pi into the display for my rowing machine. This is going to be another Hack-a-day trolling project ;-)

Sensor

Rather than interfacing into the electronics on the mower, I'm going to use the accelerometer in my Texas Instruments Chronos eZ430 watch as the sensor. With a chest strap it can also receive heart rate data an pass it on to the host.

This will work with the stock firmware - the wireless protocol is simple - and documented at http://chemicaloliver.net/arduino/graphing-ti-ez430-chronos-watch-data-in-linux/

- After connecting the RF USB dongle supplied with the watch and putthe watch into ACC transmit mode and connect to the serial port /dev/ACM0 (on linux) with baud of 115200

  • Send the hex string: 0xFF 0×07 0×03 to open a connection with the watch, it should reply 0xFF 0×06 0×03 to confirm a connection has been made
  • Accelerometer data can then be requested by sending 0xFF, 0×08, 0×07, 0×00, 0×00, 0×00, 0×00
  • The watch will then return seven bytes back in the form ff 06 07 tt xx yy zz where the last three bytes are the accelerometer values.
  • The 'tt' values are the Watch's switches, allowing you to control the whole project!

Demo sensor code

The code below reads data from the RF dongle and logs it to the screen and a file, at about 10Hz

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <math.h>

unsigned char hello_str[3] = { 0xFF, 0x07, 0x03 };
unsigned char req_data[7] = {0xFF, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00};

float cal_x = 0, cal_y = 0, cal_z = 25;

/********************************************************************/
int read_accel(int f, int *x, int *y, int *z)
{
  int nRead;
  char buffer[12];
 
  for(;;)
  {
    if(write(f,req_data,sizeof(req_data))!= sizeof(req_data))
      return -1;

    nRead =  read(f,buffer,sizeof(buffer));
    if(nRead == -1) return -1;

    if(buffer[0] == (char)0xFF && buffer[1] == 0x6 && buffer[2] == 0x7 )
    {
      *x = buffer[4]; 
      *y = buffer[5];
      *z = buffer[6];
      return 0;
    }
  } 
}  

/********************************************************************/
int waitForValidData(int f)
{
  int accel_x, accel_y, accel_z;

  /* Purge any stale data */
  if(read_accel(f, &accel_x, &accel_y, &accel_z) == -1) 
    return -1;

  for(;;)
  {
    usleep(100000);

    if(read_accel(f, &accel_x, &accel_y, &accel_z) == -1) 
      return -1;
    
    if(accel_x != 0 || accel_y != 0 || accel_z != 0) 
      break;
  }
  printf("Got first valid data\n");
  return 0;
}

/********************************************************************/
void collectData(int f)
{
  char buffer[200];
  FILE *log;

  log = fopen("logfile.txt","w");
  for(;;)
  {
    struct timeval tv;
    int accel_x, accel_y, accel_z;

    usleep(100000);

    if(read_accel(f, &accel_x, &accel_y, &accel_z) == -1) 
      return;

    gettimeofday(&tv, NULL); 
    if(accel_x == 0 && accel_y == 0 && accel_z == 0)
      sprintf(buffer, "%i.%06i ---- ---- ---- -------",(int)tv.tv_sec, (int)tv.tv_usec);
    else 
      sprintf(buffer, "%i.%06i %4i %4i %4i",(int)tv.tv_sec, (int)tv.tv_usec, accel_x, accel_y, accel_z);
    printf("%s\n", buffer);
    fprintf(log, "%s\n", buffer);
    fflush(log);
  }
}
/********************************************************************/
int main(int argc, char *argv[])
{
  int f;
  struct termios cf;

  if(argc != 2) {
    printf("usage: %s [serial port]\n",argv[0]);
    return 0;
  }

  f = open(argv[1],O_RDWR);
  if(f == -1) {
    printf("Unable to open '%s'\n",argv[1]);
    return 0;
  }

  if(tcgetattr(f, &cf) == -1) {
    printf("Unable to get termios details\n");
    return 0;
  }

  if(cfsetispeed(&cf, B115200) == -1 || cfsetospeed(&cf, B115200) == -1) {
    printf("Unable to set speed\n");
    return 0;
  }

  /* Make it a raw stream and turn off software flow control */
  cfmakeraw(&cf);
  cf.c_iflag &= ~(IXON | IXOFF | IXANY);

  if(tcsetattr(f, TCSANOW, &cf) == -1) {
    printf("Unable to set termios details\n");
    return 0;
  }

  /* See if you can get a response to a hello */
  for(;;)
  {
    unsigned char hello_response[3];
    int i;

    usleep(250000);

    if(write(f,hello_str,sizeof(hello_str)) != sizeof(hello_str)) {
      printf("Unable to say hello\n");
      return 0;
    }
 
    i = read(f,hello_response,sizeof(hello_response));
    if(i < 0) {
      printf("Unable to read response\n");
      return 0;
    }

    if(i != sizeof(hello_response))
      continue;

    if(hello_response[0] == 0xFF && hello_response[1] == 0x6 && hello_response[2] == 0x3)
      break;
  }

  printf("Waiting for valid data\n");
  if(waitForValidData(f) == -1)
  {
    printf("Unable to get valid data\n");
    return 0;
  }
 
  collectData(f); 
 
  close(f);
  return 0;
}


Personal tools