NXC: HTSmux issue (not sure if resolved)

Discussion specific to the intelligent brick, sensors, motors, and more.
Post Reply
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NXC: HTSmux issue (not sure if resolved)

Post by HaWe »

hey,
to my observation there is an HTSmux issue: it's not working correctly having attached US sensors (Mx1 ok, Mx2 or Mx3 faulty).

configuration:
HTSMUX at S1
USS at Mx1
USS at Mx2
Touch at Mx3
Touch at Mx4

all values are shown correctly EXCEPT the USS at Mx2 (always 0)

if I change or reverse the US sensor hardware it remains the same (so it's no USS hardware issue).
if I change Touch to Mx2 and USS to Mx3 then Mx2 is shown correctly, but Mx3 is always 0 (so it's no SMUX hardware issue).

Code: Select all

#include "HTSMUX-driver.h"

#define clreol  DRAW_OPT_CLEAR_EOL


task main () {

  int val = 0;
  
  // configure the port for low speed I2C
  SetSensor(S1, SENSOR_LOWSPEED);  


  while (true) {

    val = smuxSensorLegoUS(msensor_S1_1);
    TextOut(0, 48, "S1 US:", clreol);   NumOut(60, 48, val);
    
    val = smuxSensorLegoUS(msensor_S1_2);
    TextOut(0, 40, "S2 US:", clreol);   NumOut(60, 40, val);
    
    val = HTSMUXreadAnalogue(msensor_S1_3);
    TextOut(0, 32, "S3 Touch:", clreol);   NumOut(60, 32, val);
    
    val = HTSMUXreadAnalogue(msensor_S1_4);
    TextOut(0, 24, "S4 Touch:", clreol);   NumOut(60, 24, val);
    
    Wait(50);
  }
}

Code: Select all

/*
 * $Id$
 */

#ifndef __HTSMUX_DRIVER_H__
#define __HTSMUX_DRIVER_H__

/** \file HTSMUX-driver.h
 * \brief HiTechnic Sensor MUX driver
 *
 * HTSMUX-driver.h provides an API for the HiTechnic Sensor MUX.  This program
 * demonstrates how to use that API.
 *
 * Changelog:
 * - 0.1: Initial release
 * - 0.2: ADDED 
 * - int smuxSensorLegoUS(const byte muxport);
 * - int smuxSensorLegoLightRaw(const byte muxport);
 * - int smuxSensorLegoLightNorm(const byte muxport);
 * - bool smuxSetSensorLegoLight(const byte muxport, const bool active);
 * - int smuxSensorLegoSoundRaw(const byte muxport);
 * - int smuxSensorLegoSoundNorm(const byte muxport);
 * - bool smuxSetSensorLegoSound(const byte muxport, const bool dba);
 * - REMOVED:
 * - int sensorLegoUS(const byte muxport);
 * - 0.3: Added proper return code to HT Accelerometer function
 * - 0.4: Changed how sensor types are stored, now uses single dimension array
 *
 * Credits:
 * - Big thanks to HiTechnic for providing me with the hardware necessary to write and test this.
 * - John Hansen for answering my technical and philosophical questions
 * - Hunter Chiou for testing and feedback
 * - Gus Jansson for testing and feedback
 *
 * License: You may use this code as you wish, provided you give credit where it's due.
 * 
 * \author Xander Soldaat (mightor_at_gmail.com)
 * \date 08 April 2010
 * \version 0.4
 * \example HTSMUX-test1.nxc
 * \example HTSMUX-test2.nxc
 */

// Macros for coverting
#define SPORT(X)  X / 4         /*!< Convert tMUXSensor to sensor port number */
#define MPORT(X)  X % 4         /*!< Convert tMUXSensor to MUX port number */
#define smuxSensorType(X)       smuxSensor(SPORT(X),MPORT(X)) /*!< Fetch the sensor type */
#define smuxSensor(X,Y)         smuxSensorTypes[X*4+Y]    /*!< Fetch the sensor type */

// Registers
#define HTSMUX_I2C_ADDR         0x10  /*!< HTSMUX I2C device address */
#define HTSMUX_COMMAND          0x20  /*!< Command register */
#define HTSMUX_STATUS           0x21  /*!< Status register */

#define HTSMUX_MODE             0x00  /*!< Sensor mode register */
#define HTSMUX_TYPE             0x01  /*!< Sensor type register */
#define HTSMUX_I2C_COUNT        0x02  /*!< I2C byte count register */
#define HTSMUX_I2C_DADDR        0x03  /*!< I2C device address register */
#define HTSMUX_I2C_MADDR        0x04  /*!< I2C memory address register */
#define HTSMUX_CH_OFFSET        0x22  /*!< Channel register offset */
#define HTSMUX_CH_ENTRY_SIZE    0x05  /*!< Number of registers per sensor channel */

#define HTSMUX_ANALOG           0x36  /*!< Analogue upper 8 bits register */
#define HTSMUX_AN_ENTRY_SIZE    0x02  /*!< Number of registers per analogue channel */

#define HTSMUX_I2C_BUF          0x40  /*!< I2C buffer register offset */
#define HTSMUX_BF_ENTRY_SIZE    0x10  /*!< Number of registers per buffer */

// Command fields
#define HTSMUX_CMD_HALT         0x00  /*!< Halt multiplexer command */
#define HTSMUX_CMD_AUTODETECT   0x01  /*!< Start auto-detect function command */
#define HTSMUX_CMD_RUN          0x02  /*!< Start normal multiplexer operation command */

// Status
#define HTSMUX_STAT_NORMAL      0x00  /*!< Nothing going on, everything's fine */
#define HTSMUX_STAT_BATT        0x01  /*!< No battery voltage detected status */
#define HTSMUX_STAT_BUSY        0x02  /*!< Auto-dected in progress status */
#define HTSMUX_STAT_HALT        0x04  /*!< Multiplexer is halted status */
#define HTSMUX_STAT_ERROR       0x08  /*!< Command error detected status */
#define HTSMUX_STAT_NOTHING     0xFF  /*!< Status hasn't really been set yet */

// Channel modes
#define HTSMUX_CHAN_NONE        0X00  /*!< Turn off all options for this channel */
#define HTSMUX_CHAN_I2C         0x01  /*!< I2C channel present channel mode */
#define HTSMUX_CHAN_9V          0x02  /*!< Enable 9v supply on analogue pin channel mode */
#define HTSMUX_CHAN_DIG0_HIGH   0x04  /*!< Drive pin 0 high channel mode */
#define HTSMUX_CHAN_DIG1_HIGH   0x08  /*!< Drive pin 1 high channel mode */
#define HTSMUX_CHAN_I2C_SLOW    0x10  /*!< Set slow I2C rate channel mode */


/*!< Sensor types as detected by SMUX */
const byte HTSMUXAnalogue     = 0x00;   /*!< Standard Analogue Sensor */
const byte HTSMUXLegoUS       = 0x01;   /*!< Lego Ultrasound Sensor */
const byte HTSMUXCompass      = 0x02;   /*!< HiTechnic Compass Sensor */
const byte HTSMUXColor        = 0x03;   /*!< HiTechnic Colour (V1) Sensor */
const byte HTSMUXAccel        = 0x04;   /*!< HiTechnic Acceleration Sensor */
const byte HTSMUXIRSeeker     = 0x05;   /*!< HiTechnic IR Seeker (V1) Sensor */
const byte HTSMUXProto        = 0x06;   /*!< HiTechnic Prototype Board Sensor */
const byte HTSMUXColorNew     = 0x07;   /*!< HiTechnic Colour (V2) Sensor */
const byte HTSMUXIRSeekerNew  = 0x09;   /*!< HiTechnic IR Seeker (V2) Sensor */
const byte HTSMUXSensorNone   = 0xFF;   /*!< No Sensor detected */
  
/*!< Sensor and SMUX port combinations */
const byte msensor_S1_1 = 0;           /*!< NXT Sensor Port 1, SMUX Port 1 */
const byte msensor_S1_2 = 1;           /*!< NXT Sensor Port 1, SMUX Port 2 */
const byte msensor_S1_3 = 2;           /*!< NXT Sensor Port 1, SMUX Port 3 */
const byte msensor_S1_4 = 3;           /*!< NXT Sensor Port 1, SMUX Port 4 */
const byte msensor_S2_1 = 4;           /*!< NXT Sensor Port 2, SMUX Port 1 */
const byte msensor_S2_2 = 5;           /*!< NXT Sensor Port 2, SMUX Port 2 */
const byte msensor_S2_3 = 6;           /*!< NXT Sensor Port 2, SMUX Port 3 */
const byte msensor_S2_4 = 7;           /*!< NXT Sensor Port 2, SMUX Port 4 */
const byte msensor_S3_1 = 8;           /*!< NXT Sensor Port 3, SMUX Port 1 */
const byte msensor_S3_2 = 9;           /*!< NXT Sensor Port 3, SMUX Port 2 */
const byte msensor_S3_3 = 10;          /*!< NXT Sensor Port 3, SMUX Port 3 */
const byte msensor_S3_4 = 11;          /*!< NXT Sensor Port 3, SMUX Port 4 */
const byte msensor_S4_1 = 12;          /*!< NXT Sensor Port 4, SMUX Port 1 */
const byte msensor_S4_2 = 13;          /*!< NXT Sensor Port 4, SMUX Port 2 */
const byte msensor_S4_3 = 14;          /*!< NXT Sensor Port 4, SMUX Port 3 */
const byte msensor_S4_4 = 15;          /*!< NXT Sensor Port 4, SMUX Port 4 */



byte smuxSensorTypes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /*!< Array to hold scanned and detected sensor types */
byte smuxStatus[4] = {HTSMUX_STAT_NOTHING, HTSMUX_STAT_NOTHING, HTSMUX_STAT_NOTHING, HTSMUX_STAT_NOTHING}; /*!< Array to hold current state of SMUXes connected to the NXT */

// Prototypes

// HiTechnic Sensor MUX port scanning function.  This must be called before 
// any sensors can be polled
bool HTSMUXscanPorts(const byte smux);

// HiTechnic Accelerometer
bool smuxReadSensorHTAccel(const byte muxport, int &x, int &y, int &z);

// HiTechnic IR Seeker V2
bool smuxReadSensorHTIRSeeker2AC(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5);
int smuxSensorHTIRSeeker2ACDir(const byte muxport);
bool smuxReadSensorHTIRSeeker2DC(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5, byte &avg) ;
int smuxSensorHTIRSeeker2DCDir(const byte muxport);
bool smuxReadSensorHTIRSeeker(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5);
int smuxSensorHTIRSeekerDir(const byte muxport);

// HiTechnic Colour Sensor (V1/V2)
bool smuxReadSensorHTColor(const byte muxport, int &colnum, int &red, int &green, int &blue);
int smuxSensorHTColorNum(const byte muxport);

// HiTechnic Compass Sensor
int smuxSensorHTCompass(const byte muxport);

// HiTechnic EOPD Sensor
int smuxSensorHTEOPD(const byte muxport);
int smuxSensorRawHTEOPD(const byte muxport);
bool smuxSetSensorHTEOPD(const byte muxport, const bool bStandard);

// HiTechnic Gyro
int smuxSensorHTGyro(const byte muxport, const int offset);

// Standard LEGO sensors
int smuxSensorLegoUS(const byte muxport);
int smuxSensorLegoLightRaw(const byte muxport);
int smuxSensorLegoLightNorm(const byte muxport);
bool smuxSetSensorLegoLight(const byte muxport, const bool active);
int smuxSensorLegoSoundRaw(const byte muxport);
int smuxSensorLegoSoundNorm(const byte muxport);
bool smuxSetSensorLegoSound(const byte muxport, const bool dba);

// Analogue Sensor specific functions
int HTSMUXreadAnalogue (const byte muxport);
bool HTSMUXsetAnalogueInactive(const byte muxport);
bool HTSMUXsetAnalogueActive(const byte muxport);

// Digital Sensor specific functions
bool HTSMUXreadDigital (const byte muxport, byte &data[], const byte offset, const byte length);

// Internal HiTechnic Sensor MUX functions that should be not used directly
bool _HTSMUXsetMode(const byte muxport, const byte mode);
byte _HTSMUXreadStatus(const byte smux);
bool _HTSMUXsendCmd(const byte smux, const byte cmd);


 
/**
 * Send a command to the SMUX.
 *
 * command can be one of the following:
 * -HTSMUX_CMD_HALT
 * -HTSMUX_CMD_AUTODETECT
 * -HTSMUX_CMD_RUN
 *
 * Note: this is an internal function and should not be called directly
 * @param smux the SMUX port number
 * @param cmd the command to be sent to the SMUX
 * @return true if no error occured, false if it did
 */ 
bool _HTSMUXsendCmd(const byte smux, const byte cmd)  {
  byte sendMsg[];
  
  ArrayBuild(sendMsg, HTSMUX_I2C_ADDR, HTSMUX_COMMAND, cmd);

  // Send the command to the SMUX
  while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();
  I2CWrite(smux, 0, sendMsg);

  // if the HTSMUX_CMD_AUTODETECT command has
  // been given, wait 500 ms
  if (cmd == HTSMUX_CMD_AUTODETECT) {
    Wait(500);

  // Wait 50ms after SMUX is halted
  } else if (cmd == HTSMUX_CMD_HALT) {
    Wait(50);
  }
  
  // Set the status variable appropriately 
  switch(cmd) {
    case HTSMUX_CMD_HALT:
        smuxStatus[smux] = HTSMUX_STAT_HALT;
        break;
    case HTSMUX_CMD_AUTODETECT:
        smuxStatus[smux] = HTSMUX_STAT_BUSY;
        break;
    case HTSMUX_CMD_RUN:
        smuxStatus[smux] = HTSMUX_STAT_NORMAL;
        break;
  }
  
  while ((I2CCheckStatus(smux) == STAT_COMM_PENDING) && (I2CCheckStatus(smux) != NO_ERR)) Yield();
  return (I2CCheckStatus(smux) == NO_ERR);
}


/**
 * Read the value returned by the sensor attached the SMUX. This function
 * is for I2C sensors.
 * @param muxport the SMUX sensor port number
 * @param data array to hold values returned from SMUX
 * @param offset the offset used to start reading from
 * @param length the size of the I2C reply
 * @return true if no error occured, false if it did
 */
bool HTSMUXreadDigital (const byte muxport, byte &data[], const byte offset, const byte length) {
  byte sendMsg[];
  
  // Work-around for built-in macros that can't grok this.
  byte smux = SPORT(muxport);
  byte channel = MPORT(muxport);
  
  ArrayInit(data, 0, length);
  ArrayInit(sendMsg, 0, 2);
  
  // If we're in the middle of a scan, abort this call
  if (smuxStatus[smux] == HTSMUX_STAT_BUSY) {
    return false;
  // Are we ready to run
  } else if (smuxStatus[smux] != HTSMUX_STAT_NORMAL) {
    if (!_HTSMUXsendCmd(smux, HTSMUX_CMD_RUN))
      return false;
  }
	
  sendMsg[0] = HTSMUX_I2C_ADDR; // Address of SMUX
  // Buffer register
  sendMsg[1] = HTSMUX_I2C_BUF + (channel * HTSMUX_BF_ENTRY_SIZE) + offset;
  // Query the SMUX and read the response
  while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();    
  return I2CBytes(smux, sendMsg, length, data);
} 


/**
 * Read the value returned by the sensor attached the SMUX. This function
 * is for analogue sensors.
 * @param muxport the SMUX sensor port number
 * @return the value of the sensor or -1 if an error occurred.
 */
int HTSMUXreadAnalogue (const byte muxport) {
  byte sendMsg[2];
  byte readMsg[2];
  const byte count = 2;
  
  // Work-around for built-in macros that can't grok this.
  byte smux = SPORT(muxport);
  byte channel = MPORT(muxport);
    
  if (smuxStatus[smux] == HTSMUX_STAT_BUSY) {
    return false;
  // Are we ready to run
  } else if (smuxStatus[smux] != HTSMUX_STAT_NORMAL) {
    if (!_HTSMUXsendCmd(smux, HTSMUX_CMD_RUN))
      return false;
  }
  
  sendMsg[0] = HTSMUX_I2C_ADDR; // Address of SMUX
               // Buffer register
  sendMsg[1] = HTSMUX_ANALOG + (channel * HTSMUX_AN_ENTRY_SIZE);
  
  // Query the SMUX and read the response
  while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();  
  if (I2CBytes(smux, sendMsg, count, readMsg))
    return ((readMsg[0] & 0x00FF) * 4) + (readMsg[1] & 0x00FF);
  else
    return 0;
}


/**
 * Read the status of the SMUX
 *
 * The status byte is made up of the following bits:
 *
 * | D7 | D6 | D4 | D3 | D2 | D1 | D1 |
 * -D1 - HTSMUX_STAT_BATT: No battery voltage detected
 * -D2 - HTSMUX_STAT_BUSY: Auto-dected in progress status
 * -D3 - HTSMUX_STAT_HALT: Multiplexer is halted
 * -D4 - HTSMUX_STAT_ERROR: Command error detected
 *
 * Note: this is an internal function and should not be called directly 
 * @param smux the SMUX port number
 * @return the status byte
 */
byte _HTSMUXreadStatus(const byte smux) {
  byte sendMsg[];
  byte readMsg[];
  const byte count = 1;
  
  ArrayBuild(sendMsg, HTSMUX_I2C_ADDR, HTSMUX_STATUS);

  // Query the SMUX and read the response
  while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();
  if (I2CBytes(smux, sendMsg, count, readMsg))
    return readMsg[0] & 0x00FF;
  else
    return 0;
}


/**
 * Scan the specified SMUX's channels and configure them. This function must be
 * called before the sensors attached to it can be queried.
 *
 * Note: this functions takes 500ms to return while the scan is in progress.
 * @param smux the SMUX port number
 * @return true if no error occured, false if it did
 */
bool HTSMUXscanPorts(const byte smux) {
  byte sendMsg[];
  byte readMsg[];

  byte foo = 0;  
  const byte size = 1;
  
  // Initialise array
  ArrayInit(sendMsg, 0, 2);
  
  // If we're in the middle of a scan, abort this call
  if (smuxStatus[smux] == HTSMUX_STAT_BUSY)
    return false;
	
  // Always make sure the SMUX is in the halted state
  if (!_HTSMUXsendCmd(smux, HTSMUX_CMD_HALT))
    return false;

  // Commence scanning the ports and allow up to 500ms to complete
  if (!_HTSMUXsendCmd(smux, HTSMUX_CMD_AUTODETECT))
    return false;
  Wait(500);
  
  // When the SMUX is done with scanning, it reverts back to halted mode.
  smuxStatus[smux] = HTSMUX_STAT_HALT;

  // Populate the smuxSensor array with the sensor types
  for (int i = 0; i < 4; i++) {
    // Query the SMUX and read the response
    while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();
    sendMsg[0] = HTSMUX_I2C_ADDR;   // I2C Address
    sendMsg[1] = HTSMUX_CH_OFFSET + HTSMUX_TYPE + (HTSMUX_CH_ENTRY_SIZE * i);
    
    if (I2CBytes(smux, sendMsg, size, readMsg)) {
      smuxSensor(smux,i) = readMsg[0];
    } else {
      smuxSensor(smux,i) = HTSMUXSensorNone;
    }
  }
  return true;
}


/**
 * Set the mode of a SMUX channel.
 *
 * Mode can be one or more of the following:
 * -HTSMUX_CHAN_I2C
 * -HTSMUX_CHAN_9V
 * -HTSMUX_CHAN_DIG0_HIGH
 * -HTSMUX_CHAN_DIG1_HIGH
 * -HTSMUX_CHAN_I2C_SLOW
 * @param muxport the SMUX sensor port number
 * @param mode the mode to set the channel to
 * @return true if no error occured, false if it did
 */
bool _HTSMUXsetMode(const byte muxport, const byte mode) {
  // Work-around for built-in macros that can't grok this.
  byte smux = SPORT(muxport);
  byte channel = MPORT(muxport);

  byte sendMsg[];
  byte regaddr = HTSMUX_CH_OFFSET + HTSMUX_MODE + (HTSMUX_CH_ENTRY_SIZE * channel);
  
  ArrayBuild(sendMsg, HTSMUX_I2C_ADDR, regaddr, mode);
  
  // If we're in the middle of a scan, abort this call
  if (smuxStatus[smux] == HTSMUX_STAT_BUSY) {
    return false;
  } else if (smuxStatus[smux] != HTSMUX_STAT_HALT) {
	  // Always make sure the SMUX is in the halted state
	  if (!_HTSMUXsendCmd(smux, HTSMUX_CMD_HALT))
	    return false;
	}

  // Send the command to the SMUX
  while (I2CCheckStatus(smux) == STAT_COMM_PENDING) Yield();
  I2CWrite(smux, 0, sendMsg);
  
  while ((I2CCheckStatus(smux) == STAT_COMM_PENDING) && (I2CCheckStatus(smux) != NO_ERR)) Yield();
  return (I2CCheckStatus(smux) == NO_ERR);
}


/**
 * Set the mode of an analogue channel to Active (turn the light on)
 * @param muxport the SMUX sensor port number
 * @return true if no error occured, false if it did
 */
bool HTSMUXsetAnalogueActive(const byte muxport) {
  if(smuxSensorType(muxport) != HTSMUXAnalogue)
    return false;

  if (!_HTSMUXsetMode(muxport, HTSMUX_CHAN_DIG0_HIGH))
    return false;

  return _HTSMUXsendCmd(SPORT(muxport), HTSMUX_CMD_RUN);
}


/**
 * Set the mode of an analogue channel to Inactive (turn the light off)
 * @param muxport The SMUX sensor port number
 * @return True if no error occured, false if it did
 */
bool HTSMUXsetAnalogueInactive(const byte muxport) {
  if(smuxSensorType(muxport) != HTSMUXAnalogue)
    return false;

  if (!_HTSMUXsetMode(muxport, 0))
    return false;

  return _HTSMUXsendCmd(SPORT(muxport), HTSMUX_CMD_RUN);
}


/**
 * Read LEGO Ultra Sound sensor.
 *
 * Read LEGO Ultra Sound sensor on the specified smux port.
 * @param muxport The SMUX sensor port number
 * @return The LEGO US sensor reading.
 */
int smuxSensorLegoUS(const byte muxport) {
  byte sensorVal[];
  
  if (!HTSMUXreadDigital (muxport, sensorVal, 0, 1))
    return 255;
  else
    return sensorVal[0] & 0x00FF;
}


/**
 * Read HiTechnic Gyro sensor.
 *
 * Read the HiTechnic Gyro sensor on the specified smux port. The offset value should
 * be calculated by averaging several readings with an offset of zero while the 
 * sensor is perfectly still.
 * @param muxport The SMUX sensor port number.
 * @param offset The zero offset.
 * @return The Gyro sensor reading.
 */
int smuxSensorHTGyro(const byte muxport, const int offset) {
  return HTSMUXreadAnalogue (muxport) - offset;
}


/** 
 * Set sensor as HiTechnic EOPD.
 *
 * Configure the sensor on the specified port as a HiTechnic EOPD sensor.
 * @param muxport The SMUX sensor port number.
 * @param bStandard Configure in standard or long-range mode.
 * @return True if no error occured, false if it did
 */
bool smuxSetSensorHTEOPD(const byte muxport, const bool bStandard) {
  // short range is set by making the sensor analogue inactive
  if (bStandard)
    return HTSMUXsetAnalogueInactive(muxport);
  else
    return HTSMUXsetAnalogueActive(muxport);
}


/**
 * Read HiTechnic EOPD sensor (raw value).
 *
 * Read the HiTechnic EOPD sensor (raw value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return The EOPD sensor reading (raw value).
 */ 
int smuxSensorRawHTEOPD(const byte muxport) {
  return 1023 - HTSMUXreadAnalogue(muxport);
}


/**
 * Read HiTechnic EOPD sensor (processed value).
 *
 * Read the HiTechnic EOPD sensor (processed value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return The EOPD sensor reading (processed value).
 */ 
int smuxSensorHTEOPD(const byte muxport) {
  return sqrt(smuxSensorRawHTEOPD(muxport) * 10);
}


/**
 * Read HiTechnic compass.
 *
 * Read the compass heading value of the HiTechnic Compass sensor on the 
 * specified port.
 * @param muxport The SMUX sensor port number.
 * @return The compass heading.
 */
int smuxSensorHTCompass(const byte muxport) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a compass sensor
  if (smuxSensorType(muxport) != HTSMUXCompass)
    return -1;
    
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 2))
    return -1;
  else
    return ((readMsg[0]  & 0x00FF) * 2) + (readMsg[1] & 0x00FF);
}


/**
 * Read HiTechnic color sensor color number.
 *
 * Read the color number from the HiTechnic Color sensor on the specified port. 
 * @param muxport The SMUX sensor port number.
 * @return The color number.
 */
int smuxSensorHTColorNum(const byte muxport) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a colour sensor
  if ((smuxSensorType(muxport) != HTSMUXColor) 
   && (smuxSensorType(muxport) != HTSMUXColorNew))
    return -1;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 1))
    return 0;
  else
    return readMsg[0] & 0x00FF;
}


/**
 * Read HiTechnic Color values.
 *
 * Read the red, green, and blue values from the HiTechnic Color sensor. 
 * Returns a boolean value indicating whether or not the operation completed 
 * successfully
 * @param muxport The SMUX sensor port number.
 * @param colnum The colour number currently detected
 * @param red The red color value.
 * @param green The green color value.
 * @param blue The raw blue color value.
 * @return True if no error occured, false if it did
 */
bool smuxReadSensorHTColor(const byte muxport, int &colnum, int &red, int &green, int &blue) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a colour sensor
  if ((smuxSensorType(muxport) != HTSMUXColor) 
   && (smuxSensorType(muxport) != HTSMUXColorNew))
    return false;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 4))
    return false;

  colnum = readMsg[0] & 0x00FF;
  red    = readMsg[1] & 0x00FF;
  green  = readMsg[2] & 0x00FF;
  blue   = readMsg[3] & 0x00FF;
  return true;
}


/**
 * Read HiTechnic IRSeeker direction.
 * 
 * Read the direction value of the HiTechnic IR Seeker on the specified port. 
 * @param muxport The sensor port.
 * @return The IRSeeker direction.
 */
int smuxSensorHTIRSeekerDir(const byte muxport) {
  byte readMsg[];

  // Check if the attached sensor really -is- a compass sensor
  if ((smuxSensorType(muxport) != HTSMUXIRSeeker) 
   && (smuxSensorType(muxport) != HTSMUXIRSeekerNew))
    return -1;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 1))
    return 0;
  else
    return readMsg[0] & 0x00FF;
}


/**
 * Read HiTechnic IRSeeker values.
 * 
 * Read direction, and five signal strength values from the HiTechnic IRSeeker 
 * sensor. Returns a boolean value indicating whether or not the operation 
 * completed successfully. 
 * @param muxport The sensor port.
 * @param dir The direction.
 * @param s1 The signal strength from sensor 1.
 * @param s2 The signal strength from sensor 2.
 * @param s3 The signal strength from sensor 3.
 * @param s4 The signal strength from sensor 4.
 * @param s5 The signal strength from sensor 5. 
 * @return True if no error occured, false if it did
 */
bool smuxReadSensorHTIRSeeker(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a compass sensor
  if (smuxSensorType(muxport) != HTSMUXIRSeekerNew)
    return false;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 6))
    return false;

  dir = readMsg[0];
  s1  = readMsg[1];
  s2  = readMsg[2];
  s3  = readMsg[3];
  s4  = readMsg[4];
  s5  = readMsg[5];
  
  return true; 
}


/**
 * Read HiTechnic IRSeeker2 DC direction.
 * 
 * Read the DC direction value from the HiTechnic IR Seeker2 on the specified port.
 * @param muxport The sensor port.
 * @return The IRSeeker2 DC direction.
 */
int smuxSensorHTIRSeeker2DCDir(const byte muxport) {
  return smuxSensorHTIRSeekerDir(muxport);
}


/**
 * Read HiTechnic IRSeeker2 DC values.
 * 
 * Read direction, five signal strength, and average strength values from the 
 * HiTechnic IRSeeker2 sensor. Returns a boolean value indicating whether or not
 * the operation completed successfully 
 * @param muxport The sensor port.
 * @param dir The direction.
 * @param s1 The signal strength from sensor 1.
 * @param s2 The signal strength from sensor 2.
 * @param s3 The signal strength from sensor 3.
 * @param s4 The signal strength from sensor 4.
 * @param s5 The signal strength from sensor 5. 
 * @param avg The average signal strength.
 * @return True if no error occured, false if it did
 */
bool smuxReadSensorHTIRSeeker2DC(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5, byte &avg) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a compass sensor
  if (smuxSensorType(muxport) != HTSMUXIRSeekerNew)
    return false;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 0, 7))
    return false;

  dir = readMsg[0];
  s1  = readMsg[1];
  s2  = readMsg[2];
  s3  = readMsg[3];
  s4  = readMsg[4];
  s5  = readMsg[5];
  avg = readMsg[6];
  
  return true; 
}


/**
 * Read HiTechnic IRSeeker2 AC direction.
 * 
 * Read the AC direction value from the HiTechnic IR Seeker2 on the specified port.
 * @param muxport The sensor port.
 * @return The IRSeeker2 AC direction.
 */
int smuxSensorHTIRSeeker2ACDir(const byte muxport) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a compass sensor
  if (smuxSensorType(muxport) != HTSMUXIRSeekerNew)
    return -1;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 7, 1))
    return 0;
  else
    return readMsg[0] & 0x00FF;
}


/**
 * Read HiTechnic IRSeeker2 AC values.
 * 
 * Read direction, and five signal strength values from the HiTechnic IRSeeker2 
 * sensor in AC mode. Returns a boolean value indicating whether or not
 * the operation completed successfully 
 * @param muxport The sensor port.
 * @param dir The direction.
 * @param s1 The signal strength from sensor 1.
 * @param s2 The signal strength from sensor 2.
 * @param s3 The signal strength from sensor 3.
 * @param s4 The signal strength from sensor 4.
 * @param s5 The signal strength from sensor 5. 
 * @return True if no error occured, false if it did
 */
bool smuxReadSensorHTIRSeeker2AC(const byte muxport, byte &dir, byte &s1, byte &s2, byte &s3, byte &s4, byte &s5) {
  byte readMsg[];
  
  // Check if the attached sensor really -is- a compass sensor
  if (smuxSensorType(muxport) != HTSMUXIRSeekerNew)
    return false;
      
  if (!HTSMUXreadDigital (muxport, readMsg, 7, 6))
    return false;

  dir = readMsg[0];
  s1  = readMsg[1];
  s2  = readMsg[2];
  s3  = readMsg[3];
  s4  = readMsg[4];
  s5  = readMsg[5];
  
  return true;  
}
	

/**
 * Read HiTechnic acceleration values.
 * 
 * Read X, Y, and Z axis acceleration values from the HiTechnic Accelerometer 
 * sensor. Returns a boolean value indicating whether or not the operation 
 * completed successfully. 
 * @param muxport The sensor port.
 * @param x The output x-axis acceleration.
 * @param y The output y-axis acceleration.
 * @param z The output z-axis acceleration.
 * @return True if no error occured, false if it did
 */
bool smuxReadSensorHTAccel(const byte muxport, int &x, int &y, int &z) {
  byte readMsg[];
  
  if (smuxSensorType(muxport) != HTSMUXAccel)
    return false;

  if (!HTSMUXreadDigital(muxport, readMsg, 0, 6)) {
    return false;
  }

  // Convert 2 bytes into a signed 10 bit value.  If the 8 high bits are more than 127, make
  // it a signed value before combing it with the lower 2 bits.
  // Gotta love conditional assignments!
  x = (readMsg[0] > 127) ? ((readMsg[0] - 256) * 4) + readMsg[3]
                                   : (readMsg[0] * 4) + readMsg[3];

  y = (readMsg[1] > 127) ? ((readMsg[1] - 256) * 4) + readMsg[4]
                                   : (readMsg[1] * 4) + readMsg[4];

  z = (readMsg[2] > 127) ? ((readMsg[2] - 256) * 4) + readMsg[5]
                                   : (readMsg[2] * 4) + readMsg[5];
  
  return true;
}

#endif // __HTSMUX_DRIVER_H__


/**
 * Read LEGO Light sensor (raw value).
 *
 * Read LEGO Lightsensor (raw value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return Read LEGO Light sensor reading (raw value).
 */ 
int smuxSensorLegoLightRaw(const byte muxport) {
  return 1023 - HTSMUXreadAnalogue(muxport);
}


/**
 * Read LEGO Light sensor (normalised value).
 *
 * Read LEGO Lightsensor (normalised value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return Read LEGO Light sensor reading (normalised value).
 */ 
int smuxSensorLegoLightNorm(const byte muxport) {
  long val = smuxSensorLegoLightRaw(muxport);
  return (val * 100) / 1024;
}


/** 
 * Set sensor as LEGO Light sensor.
 *
 * Configure the sensor on the specified port as a LEGO Light sensor.
 * @param muxport The SMUX sensor port number.
 * @param active Configure in active or inactive mode.
 * @return True if no error occured, false if it did
 */
bool smuxSetSensorLegoLight(const byte muxport, const bool active) {
  if (!active)
    return HTSMUXsetAnalogueInactive(muxport);
  else
    return HTSMUXsetAnalogueActive(muxport);
}


/**
 * Read HiTechnic EOPD sensor (raw value).
 *
 * Read the HiTechnic EOPD sensor (raw value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return The EOPD sensor reading (raw value).
 */ 
int smuxSensorLegoSoundRaw(const byte muxport) {
  return 1023 - HTSMUXreadAnalogue(muxport);
}


/**
 * Read LEGO Sound sensor (normalised value).
 *
 * Read LEGO Sound sensor (normalised value) on the specified port.
 * @param muxport The SMUX sensor port number.
 * @return Read LEGO Sound sensor reading (normalised value).
 */ 
int smuxSensorLegoSoundNorm(const byte muxport) {
  long val = smuxSensorLegoSoundRaw(muxport);
  return (val * 100) / 1024;
}


/** 
 * Set sensor as LEGO Sound sensor.
 *
 * Configure the sensor on the specified port as a LEGO Sound sensor.
 * @param muxport The SMUX sensor port number.
 * @param dba Configure in dBA or dB mode.
 * @return True if no error occured, false if it did
 */
bool smuxSetSensorLegoSound(const byte muxport, const bool dba) {
  if (dba)
    return HTSMUXsetAnalogueInactive(muxport);
  else
    return HTSMUXsetAnalogueActive(muxport);
}

/*
 * $Id$
 */
if I outcomment the 1st USS call it remains the same (always 0 for USS at Mx3)

Code: Select all

#include "HTSMUX-driver.h"

#define clreol  DRAW_OPT_CLEAR_EOL


task main () {

  int val = 0;
  
  // configure the port for low speed I2C
  SetSensor(S1, SENSOR_LOWSPEED);
  

  while (true) {

    /*val = smuxSensorLegoUS(msensor_S1_1);
    TextOut(0, 48, "S1 US:", clreol);   NumOut(60, 48, val);        */
    
    val = HTSMUXreadAnalogue(msensor_S1_2);
    TextOut(0, 40, "S2 Touch:", clreol);   NumOut(60, 40, val);
    
    val = smuxSensorLegoUS(msensor_S1_3);
    TextOut(0, 32, "S3 US:", clreol);   NumOut(60, 32, val);
    
    val = HTSMUXreadAnalogue(msensor_S1_4);
    TextOut(0, 24, "S4 Touch:", clreol);   NumOut(60, 24, val);
    
    Wait(10);
  }
}

Last edited by HaWe on 25 Nov 2012, 22:39, edited 1 time in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HTSmux issue (not sure if resolved)

Post by HaWe »

strange.
After having plugged and unplugged and replugged all and everything several times now it works fine.
I wonder if any SMux sensor initialization routine went wrong...
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HTSmux issue (not sure if resolved)

Post by HaWe »

update:
indeed it's still rather shaky. Sometimes again certain i2c Sensors send no values and sometimes the whole SMux is not recognized at all at start-up.

Probably it's an underlying hardware issue.
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests