NXT Sensor Multiplexer

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

NXT Sensor Multiplexer

Postby darkxtidus » Tue Jan 12, 2010 11:21 pm

Hi guys, i have checked in lejos libraries and i found out that the RCX Sensor multiplexer for NXT is supported.

Now my question is:

Is the "HiTechnic Sensor Multiplexer (NSX2020)" also supported?
http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NSX2020


I tried to check in the package for libraries but i couldn't find them.



Thank you :D

dark.
darkxtidus
New User
 
Posts: 9
Joined: Tue Jan 12, 2010 12:28 am

Postby ChrisB01 » Tue Feb 09, 2010 5:44 pm

As its new, I doubt it. However if you have one you could start building the lejos library for it. If you decide to do this I have some advice (might not be useful about how I would do it but, on the other hand this is quite an advanced sensor so it wont be easy to integrate it properly).

Chris
ChrisB01
Advanced Member
 
Posts: 189
Joined: Sat Mar 15, 2008 12:19 pm
Location: UK

Postby 3DGamer » Thu Mar 18, 2010 7:05 pm

hello, I just got a Hitechnic sensormultiplexer as birthday present, now I want to use it :D.
I've already begun to write a class, this is how far I am:

Code: Select all
public class HTSensrMux extends I2CSensor {

   public static final int STATE_AUTODETECT=0;
   public static final int STATE_HALTED=1;
   public static final int STATE_RUNNING=2;
   
   protected static final int STATUS_BATTERY_BIT = 1;
   protected static final int STATUS_BUSY_BIT = 2;
   protected static final int STATUS_HALT_BIT = 4;

   protected static final byte CMD_HALT = 0;
   protected static final byte CMD_AUTODETECT = 1;
   protected static final byte CMD_RUN = 2;
   
   
   public static final byte CHMODE_DIG_SENS_BIT = 1;
   public static final byte CHMODE_9V_EN_BIT = 2;
   public static final byte CHMODE_DIG0_BIT = 4;
   public static final byte CHMODE_DIG1_BIT = 8;
   public static final byte CHMODE_SLOW_BIT = 16;
   
   public final SMuxSensorPort S1 = new SMuxSensorPort(this,1);
   public final SMuxSensorPort S2 = new SMuxSensorPort(this,2);
   public final SMuxSensorPort S3 = new SMuxSensorPort(this,3);
   public final SMuxSensorPort S4 = new SMuxSensorPort(this,4);
   
   public HTSensrMux(I2CPort port) {
      super(port);
      port.setType(TYPE_LOWSPEED_9V);
      this.setAddress(0x10/2);
   }
   
   public String getProductID(){
      byte[] buf = new byte[8];
      int failed = this.getData(0x08, buf, 8);
      if(failed!=0) return "failed. ";
      String str="l:";
      for(int i=0; i<8; i++){
         str+=(char)buf[i];
      }
      return str;
   }
   
   public int AutodetectAndRun(){
      if(getCurrentState()!=STATE_HALTED){
         setState(STATE_HALTED);
      }
      if(getCurrentState()!=STATE_HALTED) return 1;
      setState(STATE_AUTODETECT);
      if(getCurrentState()!=STATE_HALTED) return 2;
      setState(STATE_RUNNING);
      return 0;      
   }
   
   public String getSensorType(){
      byte[] buf = new byte[8];
      int failed = this.getData(0x10, buf, 8);
      if(failed!=0) return "failed. ";
      String str="l:";
      for(int i=0; i<8; i++){
         str+=(char)buf[i];
      }
      return str;
   }
     
   public String getVersion(){
      byte[] buf = new byte[8];
      int failed = this.getData(0x00, buf, 8);
      if(failed!=0) return "failed. ";
      String str="l:";
      for(int i=0; i<8; i++){
         str+=(char)buf[i];
      }
      return str;
   }
   
   public boolean isBatteryLow(){
      byte[] buf = new byte[1];
      getData(0x21,buf,1);
      return ((buf[0]&STATUS_BATTERY_BIT)!=0);
   }
   
   public int getCurrentState(){
      byte[] stat = new byte[1];
      getData(0x21,stat,1);
      if((stat[0]&STATUS_HALT_BIT)!=0) return STATE_HALTED;
      if((stat[0]&STATUS_BUSY_BIT)!=0) return STATE_AUTODETECT;
      return STATE_RUNNING;
   }
   
   public void setState(int state){
      if(state==STATE_HALTED){
         sendData(0x20, CMD_HALT);
         try{Thread.sleep(50);}catch(Exception e){}
      }else if(state==STATE_AUTODETECT){
         sendData(0x20, CMD_AUTODETECT);
         try{Thread.sleep(500);}catch(Exception e){}
      }else{
         sendData(0x20, CMD_RUN);         
      }
   }
   //------------------------------------------------------Channel read properties-------------------------------------------------
   
   public boolean isDigitalSensor(int channel){
      return  ((getSensorMode(channel)&CHMODE_DIG_SENS_BIT)!=0);
   }
   
   public byte getSensorMode(int channel){
      byte[] buf = new byte[1];
      getData(0x22+5*(channel-1),buf,1);
      return buf[0];
   }
   
   public void setSensorMode(int channel,byte mode){
      byte[] buf = new byte[]{mode};
      sendData(0x22+5*(channel-1),buf,1);
   }
   
   public short getAnalogueValue(int channel){
      byte[] buf = new byte[2];
      getData(0x36+2*(channel-1),buf,2);
      return (short)((buf[0] & 0x00FF) * 4 + (buf[1] & 0x00FF));
   }

}


and


Code: Select all

public class SMuxSensorPort implements ADSensorPort{

   protected int channel;
   protected HTSensrMux sMux;
   
   public SMuxSensorPort(HTSensrMux multiplexer, int channel){
      this.channel=channel;
      sMux=multiplexer;
   }
   
   
   public boolean readBooleanValue() {
      return readRawValue()>512;
   }

   
   public int readRawValue() {
      return sMux.getAnalogueValue(channel);
   }

   public int readValue() {
      return 1-readRawValue()/512;
   }

   public int getMode() {
      // TODO Auto-generated method stub
      return 0;
   }

   public int getType() {
      // TODO Auto-generated method stub
      return 0;
   }

   public void setMode(int mode) {
      // TODO Auto-generated method stub
      
   }

   public void setType(int type) {
      if(type==TYPE_LIGHT_ACTIVE){
         sMux.setState(HTSensrMux.STATE_HALTED);
         byte mode = sMux.getSensorMode(channel);
         mode=(byte)(mode|HTSensrMux.CHMODE_DIG0_BIT);
         sMux.setSensorMode(channel,mode);
         sMux.setState(HTSensrMux.STATE_RUNNING);
      }else if(type==TYPE_LIGHT_INACTIVE){
         sMux.setState(HTSensrMux.STATE_HALTED);
         byte mode = sMux.getSensorMode(channel);
         mode=(byte)(mode&(~HTSensrMux.CHMODE_DIG0_BIT));
         sMux.setSensorMode(channel,mode);
         sMux.setState(HTSensrMux.STATE_RUNNING);         
      }
   }

   public void setTypeAndMode(int type, int mode) {
      setType(type);
      setMode(mode);
   }

}


I'm using this paper: http://www.breigh.com/xander/HTSMUX-Tutorial-LATEST.pdf

My code already works quiet good, however yet only for analogues sensors. I've got a question about the BasicSensorport interface: Which bits of the channelmodes have to be set for the each TYPE_ and MODE_ constants? I already now that for the TYPE_ACTIVE_LIGHT the Dig0 bit has to be set (already implemented).

And something else about digital Sensors: What does the memory address register do? Is it used for specifing the register of the sensor to poll from?

Thanks for your help!
3DGamer
New User
 
Posts: 4
Joined: Sat Sep 19, 2009 11:19 am

Postby esmetaman » Mon May 03, 2010 9:46 pm

Did you test with ultrasonic sensors?
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 290
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby esmetaman » Sun May 09, 2010 7:23 pm

My current test example is the following one:

Code: Select all
import lejos.nxt.*;


public class HTSensorMuxTest {
   public static void main(String[] args) {
      HTSensorMux sm1 = new HTSensorMux(SensorPort.S1);
      LCD.drawString("" + sm1.getProductID(), 0,2);
      LCD.drawString("" + sm1.getCurrentState(), 0,3);
      LCD.drawString("" + sm1.getVersion(), 0,3);
      LCD.refresh();
      
      SMuxSensorPort us1 = sm1.S1;
      us1.setMode(us1.MODE_RAW);
      us1.setType(us1.TYPE_LOWSPEED_9V);
      //UltrasonicSensor us = new UltrasonicSensor((I2CPort) us1);
      
      while(!Button.ESCAPE.isPressed()){
         LCD.drawString("" + us1.readRawValue(), 0,0);
         LCD.drawString("" + us1.readValue(), 0,1);
      }
   }
}


What sensor did you test?
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 290
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby mightor » Mon May 10, 2010 5:20 am

Hey there peeps,

I'm the author of the tutorial linked a few posts up. Juan Antonio told me that this thread was created, so I thought I'd pipe in. I think you might be interested in the code that you can find in my driver suite. It's much better than the stuff in the tutorial as I tried to keep everything as clean as possible and the differences between the NXC and ROBOTC as small as possible. Take a look at common.h and as examples of sensor drivers, the EOPD (analogue) and LEGOUS (digital).

I saw in your code that you don't scan for the type of sensor in your AutodetectAndRun() function. This is typically the place where you would do this and keep track of it in an array of some kind. This will help a lot when initialising your SMuxSensorPort objects. The sensor type is not likely to change during the run of the program, so you may as well grab it then. The currently supported sensors are in my common.h, somewhere near the top. The numbers correspond to the sensor type as detected by the SMUX.

When you encounter a sensor that the SMUX does not support it will be configured as analogue. While it is possible to manually override a whole bunch of stuff in the SMUX to make it work with unsupported sensors, it's not really recommended (or supported by HT).

I'd be happy write a driver for this for Lejos, but my Java coding skills are a little lacking. However, I'm happy to help answer any questions you might have.

Regards,
Xander
| My Blog: I'd Rather Be Building Robots
| RobotC 3rd Party Driver Suite: [Project Page]
User avatar
mightor
Novice
 
Posts: 35
Joined: Mon Mar 09, 2009 8:25 pm

Postby esmetaman » Sat May 29, 2010 4:56 pm

Good Evening Everyone,

Xander and Me, continued with the class to manage SensorMux and for the moment, it is possible to manage US sensors and the rest of NXT 1.0 (Analogic Sensors)

I will update to SVN the class and the example.

Cheers
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 290
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby 3DGamer » Mon Jun 07, 2010 5:26 pm

Hi,
first sorry, hadn't read this topic for a long time. You can use the class with any digital sensor that does not require I2C-writing (it's not supported by the smux), however, you have to reprogram every sensor class.
Here's an example for a simple color Sensor (the hitechnic one).
Code: Select all

class SMuxColorSensor{
   protected SMuxSensorPort port;
   
   public SMuxColorSensor(SMuxSensorPort port){
      this.port=port;
      //let the SMux know that it is an Digital Sensor
      port.getMultiplexer().setSensorMode(port.getMultiplexerChannel(),HTSensrMux.CHMODE_DIG_SENS_BIT);
      //The address of the color sensor is one
      port.getMultiplexer().setDeviceAddress(port.getMultiplexerChannel(),(byte)1);
      //Read the bytes from the register address 0x42 to 0x46 (colornumber, red value, green value, blue value)
      port.getMultiplexer().setRegisterAddress(port.getMultiplexerChannel(),(byte)0x42);
   }
   
   public void getColor(int[] rgb){
      byte[] data = new byte[4];
      //read the i2cbuffer
      port.getMultiplexer().getI2CBufferData(port.getMultiplexerChannel(),data,4);
      rgb[0]=data[1]<0?255+data[1]:data[1];
      rgb[1]=data[2]<0?255+data[2]:data[2];
      rgb[2]=data[3]<0?255+data[3]:data[3];
   }
   
   
}
3DGamer
New User
 
Posts: 4
Joined: Sat Sep 19, 2009 11:19 am

Postby esmetaman » Mon Jun 07, 2010 8:32 pm

Hi!!!

I didn't know where you were. Xander and me, developed a class to read information from:

US Sensor
Touch Sensor
Sound Sensor

I will check your solution again.

Cheers friend
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 290
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby mightor » Tue Jun 08, 2010 8:17 pm

As soon as I get Eclipse working, I will start developing a generic framework for a SMUX Sensor driver.

- Xander
| My Blog: I'd Rather Be Building Robots
| RobotC 3rd Party Driver Suite: [Project Page]
User avatar
mightor
Novice
 
Posts: 35
Joined: Mon Mar 09, 2009 8:25 pm

Postby morty » Thu Nov 04, 2010 7:09 pm

Any news?
morty
New User
 
Posts: 2
Joined: Thu Nov 04, 2010 7:05 pm

Re: NXT Sensor Multiplexer

Postby clonejo » Thu Jan 05, 2012 8:04 pm

Hey there,

I just got that HiTechnic Sensor MUX for a robotics competition. I gladly found the existing class for it (lejos.nxt.addon.SensorMux) in the current release (0.9), but I needed to change the MUX' address from 0x08 to 0x10 to get it working:
Code: Select all
/**
 * Constructor
 * @param port the port
 */
public SensorMux(I2CPort port) {
   super(port, 0x10, I2CPort.LEGO_MODE, TYPE_LOWSPEED_9V);
}

Was the class just broken or has the address changed? The device claims to be of version 1.2.

As I would like to use more sensors with the MUX I'm currently expanding the class to support at least light sensors (incl. switching the floodlight). I also have a HiTechnic Accelerometer to test, though I don't need to use it through the MUX.

clonejo
clonejo
New User
 
Posts: 10
Joined: Thu Dec 16, 2010 2:38 pm

Re: NXT Sensor Multiplexer

Postby skoehler » Thu Jan 05, 2012 8:18 pm

clonejo wrote:Was the class just broken or has the address changed?


Some versions ago, we changed from using the bits 0-6 as the I2C address to using bits 1-7. The advantage is, that this address format is used by all other platforms (NXC, RobotC, etc.) and also usually matches the values found in the datasheets. When that change happened, we had to shift all adresses by 1 bit (0x08 << 1 = 0x10).

However, this class must have been forgotten. I checked that all other drivers (e.g. for RobotC) use 0x10 and fixed the leJOS driver. The fix will be contained in 0.9.1.
skoehler
leJOS Team Member
 
Posts: 1421
Joined: Thu Oct 30, 2008 4:54 pm

Re: NXT Sensor Multiplexer

Postby slinkydev » Wed Feb 19, 2014 4:33 pm

I'm trying to use SensorMux for 2 light sensors and one ultrasonic sensor. What i have to do for get light value and to switch on the floodlight. I've tried to use the SensorMux class, but they don't work. Anyone can help me? :)
slinkydev
New User
 
Posts: 1
Joined: Wed Feb 19, 2014 4:28 pm

Re: NXT Sensor Multiplexer

Postby kirkpthompson » Fri Feb 21, 2014 10:00 pm

Search and ye shall find http://www.lejos.org/forum/viewtopic.php?f=7&t=3346&p=16681&hilit=SensorMux#p16681. I think there are a lot more hits as well you should investigate. From my limited perusal, it appears the US doesn't work so well with that mux.

-K
Leg Godt!
User avatar
kirkpthompson
leJOS Team Member
 
Posts: 304
Joined: Wed Dec 05, 2007 1:27 am
Location: New Mexico, USA


Return to NXJ Software

Who is online

Users browsing this forum: Yahoo [Bot] and 3 guests

more stuff