float gryo_axis_reading_linked(ubyte axis){
 // ubyte axis definitions
 // 0x00 - x-axis
 // 0x01 - y-axis
 // 0x02 - z-axis

 ubyte I2Csnd[3];        //
 I2Csnd[0] = 2;      // Sending address, register.
 I2Csnd[1] = 0xD2;   // I2C Address of gyro.
 ubyte I2Crec[2];    // We are looking for a single byte returned.

 ubyte hb = 0;
 ubyte lb = 0;

 // We will set the value of divisor.  This is important to get a scaled output in dps.
 int divisor = 128;
 if(full_scale_range == 0x10) divisor = 64;
 if(full_scale_range == 0x30) divisor = 16;

 if(axis == 0x00) {               // x-axis
  I2Csnd[2] = 0x28;    // Register of the data we're requesting.
  sendI2CMsg(S1, I2Csnd[0], 2);     // (Port 1, Message Array, Reply Size)
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 2);   // (Port 1, Reply Array, Bytes to Read)

  // hb = gyro_axis_reading_byte(0x29);
  // lb = gyro_axis_reading_byte(0x28);
  lb = I2Crec[0];
  hb = I2Crec[1];
 }
 if(axis == 0x01) {               // y-axis
  I2Csnd[2] = 0x2B;    // Register of the data we're requesting.
  sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 2);   // (Port 1, Reply Array, Bytes to Read)

  // ubyte result = I2Crec[0];

  // hb = gyro_axis_reading_byte(0x2B);
  // lb = gyro_axis_reading_byte(0x2A);
  hb = I2Crec[0];
  lb = I2Crec[1];
 }
 if(axis == 0x02) {               // z-axis
  I2Csnd[2] = 0x2D;    // Register of the data we're requesting.
  sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 2);   // (Port 1, Reply Array, Bytes to Read)


  // hb = gyro_axis_reading_byte(0x2D);
  // lb = gyro_axis_reading_byte(0x2C);
  hb = I2Crec[0];
  lb = I2Crec[1];
 }
 float val = (lb+((long)(hb<<8)))/divisor;  // Assemble the final number by assembling the two bytes,
                                           // and dividing it by the divisor (defined in the gyro startup,
                                           // to get a properly scaled long.
 return val;
}
void start_gyro(ubyte range){
  ubyte I2Csnd[4];
  I2Csnd[0] = 3;    // Sending address, register, value.
  I2Csnd[1] = 0xD2; // I2C Address of gyro.
  ubyte I2Crec[1];        // We are looking for a single byte returned.

  // full_scale_range =  + 0x80;

  //Write CTRL_REG1
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x20;      // Register address of CTRL_REG1
    I2Csnd[3] = 0x0F;      // Enable all axes. Disable power down.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG2
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x21;                  // Register address of CTRL_REG2
    I2Csnd[3] = 0x00;                  // No High Pass Filter
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);   // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG3
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x22;      // Register address of CTRL_REG3
    I2Csnd[3] = 0x08;      // No interrupts.  Date ready.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG4
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x23;      // Register address of CTRL_REG4
    I2Csnd[3] = range+0x80;     // Full scale range.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG5
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x24;      // Register address of CTRL_REG5
    I2Csnd[3] = 0x00;      // Enable all axes. Disable power down.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

   // Set divisor so that the output of our gyro axis readings can be turned
   // into scaled values.
   ///////////////////////////////////////////////////////////////////////////
    if(full_scale_range == 0) divisor = 128;      // Full scale range is 250 dps.
    if(full_scale_range == 0x10) divisor = 64;    // Full scale range is 500 dps.
    if(full_scale_range == 0x30) divisor = 16;    // Full scale range is 2000 dps.

}
// Set the sensor to the selected frequency
void setHz(tSensors link, byte hertz) {
  byte msg[4] = { 3, 0x02, 0x41, 0x00 };

  if (hertz == 50) {
    msg[3] = 0x35;
  } else if (hertz == 60) {
    msg[3] = 0x36;
  } else {
    playSound(soundException);
    eraseDisplay();
    displayCenteredTextLine(3, "Wrong freq.");
    displayCenteredTextLine(3, "specified");
    sleep(5000);
    stopAllTasks();
  }

  while (nI2CStatus[link] == STAT_COMM_PENDING){
    sleep(5);
  }

  sendI2CMsg(link, &msg[0], 0);

  if (nI2CStatus[link] == ERR_COMM_BUS_ERR) {
    playSound(soundException);
    eraseDisplay();
    displayCenteredTextLine(3, "Error setting");
    displayCenteredTextLine(3, "sensor to 50Hz");
    sleep(5000);
    stopAllTasks();
  }
}
예제 #4
0
void start_gyro(){
  ubyte I2Csnd[4];
  I2Csnd[0] = 3;    // Sending address, register, value.
  I2Csnd[1] = 0xD2; // I2C Address of gyro.
  ubyte I2Crec[1];        // We are looking for a single byte returned.

  //Write CTRL_REG1
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x20;      // Register address of CTRL_REG1
    I2Csnd[3] = 0x0F;      // Enable all axes. Disable power down.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG2
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x21;                  // Register address of CTRL_REG2
    I2Csnd[3] = 0x00;                  // No High Pass Filter
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);   // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG3
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x22;      // Register address of CTRL_REG3
    I2Csnd[3] = 0x08;      // No interrupts.  Date ready.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG4
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x23;      // Register address of CTRL_REG4
    I2Csnd[3] = 0x00;      // Full scale range.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  //Write CTRL_REG5
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x24;      // Register address of CTRL_REG5
    I2Csnd[3] = 0x00;      // Enable all axes. Disable power down.
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)
}
예제 #5
0
sub NunchukGetParamter(tSensors port, byte i2c_cmd)
{
  // Initialize the Nunchuk
   SensorType[port] = sensorI2CCustom;

   sendI2CMsg(port, CMDNunchukInit[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ;


  CMDNunchukWrite[2] =i2c_cmd;


   sendI2CMsg(port, CMDNunchukWrite[0], 0);


  while (nI2CStatus[port] == STAT_COMM_PENDING) ;
  byte count = 6;

   sendI2CMsg(port, CMDNunchukRead[0], count);


  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // Wait for I2C bus to be ready


  if(nI2CBytesReady[port] == count){


     readI2CReply(port, outbuf[0], 6);

    for(int i=0; i<count; i++ ){
       outbuf1[i]=ubyteToInt(outbuf[i]);   //ubyte workaround for RobotC
      outbuf1[i]=(outbuf1[i]^0x17) + 0x17;
    }
  }
  else {

     memset(outbuf, 0, 0);
  }
}
예제 #6
0
sub NunchukGetParamter(tSensors port, byte i2c_cmd)
{
  // Initialize the Nunchuk
  SensorType[port] = sensorI2CCustom;

  //Ask for 0 bytes
  sendI2CMsg(port, CMDNunchukInit[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // ROBOTC Wait for I2C bus to be ready

  //Write at 0x00: 6 Bytes of sensor values
  CMDNunchukWrite[2] =i2c_cmd;

  //Write Nunchuk register address
  sendI2CMsg(port, CMDNunchukWrite[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // ROBOTC Wait for I2C bus to be ready

  byte count = 6;
  //Ask for count bytes
  sendI2CMsg(port, CMDNunchukRead[0], count);

  while (nI2CStatus[port] == STAT_COMM_PENDING) ; // Wait for I2C bus to be ready

  if(nI2CBytesReady[port] == count){

    //Read data from buffer
    readI2CReply(port, outbuf[0], 6);

    for(int i=0; i<count; i++ ){
      outbuf1[i]=ubyteToInt(outbuf[i]);   //ubyte workaround for ROBOTC
      outbuf1[i]=(outbuf1[i]^0x17) + 0x17;
    }
  }
  else {
    // error
    memset(outbuf, 0, 0);
  }
}
//IR SENSOR TASK
task IR_Sense(){

	ubyte request[3];  // I2C request message
	ubyte reply[6];		// accelerometer returns 7 values
	int replyLen;			// length of reply array.
	tSensors port;			// port the sensor is attached to.

	// which port is the accelerator hooked up to?
	port = S4;

	// Ensure the sensor is configured correctly
	SensorType[port] = sensorI2CCustom;

	eraseDisplay();


	while (true) {
		// Read the data from the sensor
		// setup the request message....
		request[0] = 2;             // Message size is 2 bytes..
		request[1] = I2C_ADDR; // I2C Address of sensor(0x02)
		request[2] = REG_OFFSET;		// location of registers to read 0x42
		replyLen = 6;								// how many registers to read

		// send request message to sensor.
		sendI2CMsg(port, &request[0], replyLen);

		// wait for a reply on the sensor port.
		// also check for sensor error...
		if (!waitForI2C(port)) {
			displayBigTextLine(4, "Error 1.");
			wait1Msec(2000);
			stopAllTasks();
		}

		// read the reply from the sensor.
		readI2CReply(port, &reply[0], replyLen);

		// make sure the bus is clear...
		// check for error.
		if (!waitForI2C(port)){
			displayBigTextLine(4, "Error 2.");
			wait1Msec(2000);
			stopAllTasks();
		}

		//Waits, then updates BrightLight value
		wait1Msec(5);
		BrightLight = reply[0];
	}
}
예제 #8
0
// Accel axis reading gets 10 bits of axis reading data.
long accl_axis_reading_10(ubyte reg){

  byte LSB = 0x00;       // Least significant bit of reading.
  byte MSB = 0x00;       // Most significant bit of reading.
  long axis_reading = 0;  // This will be the assembled reading.

  ubyte I2Csnd[3];        //
  I2Csnd[0] = 2;          // Sending address, register.
  I2Csnd[1] = accl_read;  // I2C Address of accl.
  I2Csnd[2] = reg;        // First Register of the data we're requesting.

  byte I2Crec[1];        // We are looking for a single byte returned each time.

  // Get Least Signifcant Bit of reading.
  sendI2CMsg(S1, I2Csnd[0], 1);     //  Port 1, Message Array, Reply Size
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 1);   //  Port 1, Reply Array, Bytes to Read

  LSB = I2Crec[0]; // & 0xFF;    // Save the LSB to record.
  wait1Msec(10);      // Wait some time for clean I2C.
  I2Csnd[2] = reg+1;  // Get the second register information.

  // Get Most Signifcant Bit of reading.
  sendI2CMsg(S1, I2Csnd[0], 1);     //  Port 1, Message Array, Reply Size
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 1);   //  Port 1, Reply Array, Bytes to Read

  MSB = I2Crec[0]; // & 0xFF;    // Save the MSB to record.
  int iLSB = LSB;
  int iMSB = (MSB)<<8;

  axis_reading = LSB + (MSB<<8 );
  if(axis_reading > 512){
    axis_reading >>= 8;
    axis_reading <<= 8;
    //axis_reading = ~axis_reading;
    axis_reading *= -1;
  }
//Retrieve data from the sound sensor
void i2c_read_registers_text(ubyte register_2_read, int message_size, int return_size)
{
  memset(I2Creply, 0, sizeof(I2Creply));
    message_size = message_size+3;

  I2Cmessage[0] = message_size;    // Messsage Size
  I2Cmessage[1] = ARDUINO_ADDRESS;
  I2Cmessage[2] = register_2_read; // Register
  sendI2CMsg(S1, &I2Cmessage[0], return_size);
  wait1Msec(20);

  readI2CReply(ARDUINO_PORT, &I2Creply[0], return_size);

  int i = 0,top=0;
  //Pitch
 	if(cmd==1)
 		writeDebugStreamLine("%d", (int)I2Creply[0]+(int)I2Creply[1]*256);

 	//Sound Power Level
  else if(cmd==2)
  	//For detecting clap
  	//if((int)I2Creply>85)
  	writeDebugStreamLine("%i", (int)I2Creply[0]);

  //FFT
  else if(cmd==3)
  {
  	for(int x = 0; x <return_size; x++)
  		{
  		writeDebugStream("%i", I2Creply[x]);
  		writeDebugStream(" ");
 			}
 		writeDebugStreamLine(" ");

 		//Graphic Equalizer
 		nxtEraseRect(6,62,99,6);
 		nxtDrawLine(5,2,5,61);
 		nxtDrawLine(2,5,95,5);
 		for(int j=0;j<return_size;j++)
 		{
 			top=I2Creply[j]+5;
 			if(top>61)
 				top=61;
 			nxtDrawRect(5+6*j,top,5+6*(j+1),5);
 		}

  }

}
//Send command to the processor
void i2c_write_registers(ubyte register_2_write, int message_size, int return_size, ubyte byte1, ubyte byte2){
  memset(I2Creply, 0, sizeof(I2Creply));

  message_size = message_size+3;

  I2Cmessage[0] = message_size;    // Messsage Size
  I2Cmessage[1] = ARDUINO_ADDRESS;
  I2Cmessage[2] = register_2_write; // Register

  I2Cmessage[3] = byte1;
  I2Cmessage[4] = byte2;
  //I2Cmessage[5] = byte3;

  sendI2CMsg(ARDUINO_PORT, &I2Cmessage[0], return_size);
  wait1Msec(20);
}
예제 #11
0
// Acell axis_reading gets a byte of axis reading data.
byte accl_axis_reading_8(ubyte reg){
  ubyte I2Csnd[3];        //
  I2Csnd[0] = 2;      // Sending address, register.
  I2Csnd[1] = accl_read;   // I2C Address of accl.
  I2Csnd[2] = reg;    // Register of the data we're requesting.

  byte I2Crec[1];        // We are looking for a single byte returned.
                         // Must be signed.  We're looking for a number between -128 and 128

  sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  wait1Msec(10);
  return I2Crec[0];
}
예제 #12
0
// Acell axis_reading gets a byte of axis reading data
ubyte accl_axis_reading(ubyte reg){
  ubyte I2Csnd[3];        //
  I2Csnd[0] = 2;      // Sending address, register.
  I2Csnd[1] = 0x3A;   // I2C Address of accl.
  I2Csnd[2] = reg;    // Register of the data we're requesting.

  ubyte I2Crec[1];        // We are looking for a single byte returned.

  sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
  wait1Msec(10);
  readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)

  ubyte result = I2Crec[0];
  wait1Msec(10);
  return I2Crec[0];
}
예제 #13
0
void start_accl(){
  ubyte I2Csnd[4];
  I2Csnd[0] = 3;    // Sending address, register, value.
  I2Csnd[1] = 0x3A; // I2C Address of Accelerometer.
  ubyte I2Crec[1];        // We are looking for a single byte returned.

  //Set the Mode Control
  ////////////////////////////////////////////////////////////////////////////
    I2Csnd[2] = 0x16;       // Register address of Mode Control
    I2Csnd[3] = 0x09;       // 0x05 For 2G
                            // 0x09 For 4G
                            // 0x01 For 8G
    sendI2CMsg(S1, I2Csnd[0], 1);     // (Port 1, Message Array, Reply Size)
    wait1Msec(10);
    readI2CReply(S1, I2Crec[0], 1);  // (Port 1, Reply Array, Bytes to Read)
}
void i2c_read_registers_text(ubyte register_2_read, int message_size, int return_size){
  memset(I2Creply, 0, sizeof(I2Creply));
    message_size = message_size+3;

  I2Cmessage[0] = message_size;    // Messsage Size
  I2Cmessage[1] = ARDUINO_ADDRESS;
  I2Cmessage[2] = register_2_read; // Register
  sendI2CMsg(S1, &I2Cmessage[0], return_size);
  wait1Msec(20);

  readI2CReply(ARDUINO_PORT, &I2Creply[0], return_size);

  int i = 0;
  while(true){
    writeDebugStream("%c", I2Creply[i]);
    i++;
    if(I2Creply[i] == 0) break;
  }
  writeDebugStreamLine(" ");
}
예제 #15
0
task SonarDeviceDriver()
{
  //
  // Message constants for Lego Sonar (Ultra Sonic) sensor
  //
  const ubyte kSonarID               = 2;
  const ubyte kContinuousMeasurement = 0x02;  // 0x01 for single shot mode, 0x02 for continuous measurement
  const ubyte kInitializeSonar       = 0x41;
  const ubyte kReadSonarResult       = 0x42;
  const ubyte kReset                 = 0x04;  // for a warm reset
  const ubyte kSetInterval           = 0x40;  // sets the interval at continuous measurement
  const ubyte kInterval              = 0x01;  // The interval

  //
  // I2C Message definition for SONAR sensor
  //
  static const byte kSonarInitialize[4] = {3, kSonarID, kInitializeSonar, kContinuousMeasurement};
  static const byte kSonarReset[4]      = {3, kSonarID, kInitializeSonar, kReset};
  static const byte kSonarInterval[4]   = {3, kSonarID, kSetInterval, kInterval};
  static const byte kSonarRead[3]       = {2, kSonarID, kReadSonarResult};

  //
  //  state machine for SONAR "device driver"
  //
  typedef enum
  {
  	stateInitializing,
  	stateWaitForInitDone,
  	stateSendPollMessage,
  	stateWaitingForReply,
  	stateResetting,
  	stateWaitForReset,
  	stateSettingInterval,
  	stateWaitForSettingInterval
  } TSonarState;

  static TSonarState nSonarState;
  long lastTime;
  long interval;


  //
  // Set up port 'kTestPort' as user defined I2C sensor
  //

  nI2CRetries = 0;
  SensorType[kTestPort] = sensorI2CCustom9V;
	nSonarState = stateResetting;
  while(true)
  {
  	//
  	// Loop forever, polling the SONAR sensor
  	//
  	switch (nSonarState)
	  {
	  case stateResetting:
	  	//
	  	// Send rest message to Sonar sensor
	  	//
	  	sendI2CMsg(kTestPort, kSonarReset[0], 0);
	  	nSonarState = stateWaitForReset;
	  	break;

	  case stateWaitForReset:
	  	//
	  	// Wait for Sonar sensor warm reset to complete
	  	//
	  	switch (nI2CStatus[kTestPort])
	  	{
  		case NO_ERR:
		  	nSonarState = stateInitializing;
		  	wait1Msec(kDelayBForHWStartup);
		  	break;

  		case STAT_COMM_PENDING:
  			// Keep waiting for reply. I2C messaging is not complete
  			wait1Msec(1);
  			break;

  		default:
  		case (TI2CStatus) ERR_COMM_BUS_ERR:
		  	// re-initialize sensor. An I2C messaging error occurred.
     		PlaySound(soundException);
		  	nSonarState = stateResetting;
		  	break;
			}
			break;

	  case stateSettingInterval:
	  	//
	  	// Send initialize message to Sonar sensor
	  	//
	  	sendI2CMsg(kTestPort, kSonarInterval[0], 0);
	  	nSonarState = stateWaitForSettingInterval;
	  	break;

	  case stateWaitForSettingInterval:
	  	//
	  	// Wait for Sonar sensor initialization to complete
	  	//
	  	switch (nI2CStatus[kTestPort])
	  	{
  		case NO_ERR:
		  	nSonarState = stateSendPollMessage;
		  	wait1Msec(kDelayBForHWStartup);
		  	break;

  		case STAT_COMM_PENDING:
  			// Keep waiting for reply. I2C messaging is not complete
  			wait1Msec(1);
  			break;

  		default:
  		case (TI2CStatus) ERR_COMM_BUS_ERR:
		  	// re-initialize sensor. An I2C messaging error occurred.
     		PlaySound(soundException);
    		nSonarState = stateResetting;
		  	break;
			}
			break;


			case stateInitializing:
	  	//
	  	// Send initialize message to Sonar sensor
	  	//
	  	sendI2CMsg(kTestPort, kSonarInitialize[0], 0);
	  	nSonarState = stateWaitForInitDone;
	  	break;

	  case stateWaitForInitDone:
	  	//
	  	// Wait for Sonar sensor initialization to complete
	  	//
	  	switch (nI2CStatus[kTestPort])
	  	{
  		case NO_ERR:
		  	nSonarState = stateSettingInterval;
		  	wait1Msec(kDelayBForHWStartup);
		  	break;

  		case STAT_COMM_PENDING:
  			// Keep waiting for reply. I2C messaging is not complete
  			wait1Msec(1);
  			break;

  		default:
  		case (TI2CStatus) ERR_COMM_BUS_ERR:
		  	// re-initialize sensor. An I2C messaging error occurred.
     		PlaySound(soundException);

		  	nSonarState = stateResetting;
		  	break;
			}
			break;

	  case stateSendPollMessage:
	  	//
	  	// Ready to send next polling message to Sensor
	  	//
	  	nI2CBytesReady[kTestPort] = 0; // Clear any ending bytes
	  	sendI2CMsg(kTestPort, kSonarRead[0], kSonarReplySize);
	  	nSonarState = stateWaitingForReply;
	  	break;


	  case stateWaitingForReply:
	  	//
	  	// Wait for reply from SONAR sensor
	  	//
	  	switch (nI2CStatus[kTestPort])
	  	{
  		case NO_ERR:
		  	// Reply from SONAR sensor is ready to be read.
		  	//    - Update sensor value
		  	//    - Setup to send next polling message.


		  	//
		  	// Read the SONAR value and store it in "SensorValue" array so that it can be used
		  	// by other tasks as a standard sensor.
		  	//
   	  	memset(replyMsg,0x00,kSonarReplySize);
		  	readI2CReply(kTestPort, replyMsg[0], kSonarReplySize);
		  	SensorValue[kTestPort]=replyMsg[0];
		  	nSonarState = stateSendPollMessage;
		  	if (resetAfterEveryRead) nSonarState= stateResetting;
        interval=nSysTime-lastTime;
        lastTime=nSysTime;
		  	//
		  	// Sonar hardware delay. If the next poll request is immediately sent to
		  	// the SONAR sensor, then the message gets corrupted and generates a
		  	// 'ERR_COMM_BUS_ERR' error. So we'll put a little delay in here. I'm not
		  	// certain if this is a problem in the sonar sensor or a problem in the
		  	// bit-banged firmware trying to do too many things in one timeslice or
		  	// a problem in the ROBOTC firmware. The error message is that when
		  	// transmitting the next polling I2C message an ack is not received by the
		  	// the ARM processor after transmitting a byte of the message. Suspicion
		  	// is that this is bug in SONAR sensor.
		  	//
		  	// We really only need to wait a few msec to fix above problem. But might as
		  	// well go ahead and wait longer because sonar pulses are only sent out on a
		  	// 50 to 80 period.
		  	//
		  	if (kDelayBForHWStartup != 0)
					wait1Msec(kDelayBetweenPolls);
		  	break;

  		case STAT_COMM_PENDING:
  			// Insert short wait for reply. I2C messaging xmit/rcv is not complete
  			wait1Msec(1);
  			break;

  		default:
  		case (TI2CStatus) ERR_COMM_BUS_ERR:
		  	// re-initialize sensor. An I2C messaging error occurred.
  		  PlaySound(soundException);
		  	nSonarState = stateResetting;
  			wait1Msec(2);
		  	break;
			}
			break;
		}
	}
	return;
}
예제 #16
0
/*---------------------------------------------------------------------------*/
i2cStatus
i2cWriteData( char address, char *buf, int buflen, int replylen = 0 )
{
    static  bool init = true;
    i2cStatus   status = kMessageSuccess;
    char    txbuf[34];

    // 32 bytes max buffer is determined by the firmware
    if( buflen > MAX_I2C_MESSAGE )
        return( kMessageTooLong );

    // We need to send one message to disable IME polling
    // Or enable termination
    if( init ) {
        // Dummy message
        txbuf[0] = 1;
        txbuf[1] = 0;
        txbuf[2] = 0;
        sendI2CMsg( txbuf, 0 );

        // We must wait for the I2C state machine to timeout
        // or the disable termination message to be sent to an IME
        wait1Msec(100);
        init = false;
    }

    // Loop waiting for last message to be sent
    int timeout = DEFAULT_I2C_TIMEOUT;
    while( nI2CStatus != i2cStatusDone && timeout > 0) {
        timeout--;
        wait1Msec(1);
    }

    // We waited too long for the message to be sent
    if(timeout == 0) {
        // Check and see if we are stuck on Start Bit or Address send
        if( nI2CStatus == i2cStatusStart || nI2CStatus == i2cStatusAddress )
            status = kMessageError;
        else
            status = kMessageSending;
    }

    // Setup message, first byte is data length, second is address
    txbuf[0] = buflen;
    txbuf[1] = address;

    // Copy transmit data
    for(int i=0;i<buflen;i++)
        txbuf[i+2] = buf[i];

    // Transmit
    sendI2CMsg( txbuf, replylen );

    // look at status, sort of meaningless
    // The message will either be sent or block waiting for ACK
    // There is no timeout on the low level code we can use
    if( nI2CStatus == i2cStatusStart )
        status = kMessageError;

    return( status );
}
예제 #17
0
task main()
{
  int hUpper, hLower, heading;
  TButtons nBtn;

  SensorType[CS] = sensorI2CCustom;
  wait10Msec(5);
  nI2CBytesReady[CS]=0;
  while(nI2CStatus[CS]== STAT_COMM_PENDING)
  wait1Msec(2);

  byte replyMessage[6];

  TI2C_Output sOutput;

  while(true)
  {
    nxtDisplayTextLine(1, "Mode = Read");
    nI2CBytesReady[CS] = 0;
    sOutput.nMsgSize = 2;                  //read the value from the sensor
    sOutput.nDeviceAddress = 0x02;
    sOutput.nLocationPtr = 0x42;
    sendI2CMsg(CS, sOutput.nMsgSize, 6);

    while (nI2CStatus[CS] == STAT_COMM_PENDING)
      wait1Msec(2);

    if (nI2CStatus[CS] == NO_ERR)
    {
      readI2CReply(CS, replyMessage[0], 6);            //get the compass heading
      hUpper = (replyMessage[0] & 0x00FF);
      hLower = (replyMessage[1] & 0x00FF);
      heading = (hUpper << 1) | hLower ;                //convert contents of 0x44 0x45

      nxtDisplayTextLine(4, "U-val %d", hUpper);
      nxtDisplayTextLine(5, "L-val %d", hLower);
      nxtDisplayTextLine(6, "Heading = %d", heading);

    }
    else
    {
      nxtDisplayTextLine(1, "i2c err %d", nI2CStatus[CS]);
    }

  //check if a button has been pressed.

  nBtn = nNxtButtonPressed; // check for button press

     switch (nBtn)
     {
        case kLeftButton:
           {
              PlayTone(440,1000);
              sOutput.nMsgSize = 3;
              sOutput.nDeviceAddress = 0x02;
              sOutput.nLocationPtr = 0x41;               //Calibration mode command
              sOutput.nCompassMode = 0x43;

              nI2CBytesReady[CS] = 0;
               sendI2CMsg(CS, sOutput.nMsgSize, 0);
               wait1Msec(40);
               while ((nBtn = nNxtButtonPressed) != kRightButton)
                 {                        //wait for the right button to be pressed before leaving cal mode;
                    nxtDisplayTextLine(1, "Mode = Cal ");
                    wait1Msec(1000);
                    PlaySound(soundBlip);
                 }
              break;
           }
         case kRightButton:
            {
               PlaySound(soundBeepBeep);

               sOutput.nMsgSize = 3;
              sOutput.nDeviceAddress = 0x02;
              sOutput.nLocationPtr = 0x41;
               sOutput.nCompassMode   = 0x00;                  //Read mode command
              nI2CBytesReady[CS] = 0;
               sendI2CMsg(CS, sOutput.nMsgSize, 0);
               wait1Msec(1250);                                    //wait for the cal info to be saved
               break;
           }
      }

  }
}
예제 #18
0
bool getI2CInfo(const tSensors nIntPort, string& sManufacturer, string& sType)
{
  tSensors nPort = nIntPort;
  TSensorTypes nSaveSensorType;
  ubyte nTemp[9];
  bool bI2CType;
  static const ubyte kReadManufacturer[] = {2, 0x02, 0x08};
  static const ubyte kReadSensorType[]   = {2, 0x02, 0x10};

  nSaveSensorType = SensorType[nPort];
  SensorType[nPort] = sensorI2CCustom;
  wait1Msec(50);

  while (true)
  {
    switch (nI2CStatus[nPort])
    {
    case NO_ERR:
    case ERR_COMM_BUS_ERR:
      break;

    default:
    case STAT_COMM_PENDING:
      wait1Msec(1);
      // Keep waiting for reply. I2C messaging is not complete
      continue;
    }
    break;
  }

  bI2CType = false;
  sendI2CMsg(nPort, kReadManufacturer[0], 8);
  while (true)
  {
    switch (nI2CStatus[nPort])
    {
    case NO_ERR:
    case ERR_COMM_BUS_ERR:
      bI2CType = true;
      break;

    default:
    case STAT_COMM_PENDING:
      wait1Msec(1);
      // Keep waiting for reply. I2C messaging is not complete
      continue;
    }
    break;
  }
  if (!bI2CType)
  {
    sManufacturer = "";
    sType         = "";
    SensorType[nPort] = nSaveSensorType;
    return false;
  }
  readI2CReply(nPort, nTemp[0], 8);
  nTemp[8] = 0;
  strcpy(sManufacturer, nTemp);


  sendI2CMsg(nPort, kReadSensorType[0], 8);
  while (true)
  {
    switch (nI2CStatus[nPort])
    {
    case NO_ERR:
    case ERR_COMM_BUS_ERR:
      break;

    default:
    case STAT_COMM_PENDING:
      wait1Msec(1);
      // Keep waiting for reply. I2C messaging is not complete
      continue;
    }
    break;
  }
  if (!bI2CType)
  {
    sManufacturer = "";
    sType         = "";
    SensorType[nPort] = nSaveSensorType;
    return false;
  }
  readI2CReply(nPort, nTemp[0], 8);
  nTemp[8] = 0;
  strcpy(sType, nTemp);
  SensorType[nPort] = nSaveSensorType;
  return true;
}