NXC: HT TouchMux Sensor gives faulty readings

Discussion specific to the intelligent brick, sensors, motors, and more.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by afanofosc »

The if statement absolutely should work without ==0x08. This shows true:

Code: Select all

task main()
{
  int sensor=0xFF;
  
  if (sensor&0x08)
    TextOut(0, LCD_LINE1, "true");
  else
    TextOut(0, LCD_LINE1, "false");
  while(true);
}
Doing multiplication or divistion with a touch sensor value that is 0 or 1 really doesn't make sense to me. If the sensor value is zero then whatever the complicated math operations you are doing are a complete waste of time. And if the sensor value is 1 then there is no sense in multiplying the sensor value to whatever else you are calculating. If you want it in a single line then use ?: like this:

Code: Select all

  float value = t1 ? sqrt(Random(40))*cos(PI)-5*42+Random() : 0;
Here it doesn't matter what t1 is. It can be zero or non-zero. You don't waste any time multiplying this value into the rest of your calculations. You can do the same kind of thing for adding or subtracting a 1 or 0 based on the value (zero or non-zero) of t1.

Maybe if you give me an example of using a 0/1 touch sensor value in a mathematical equation it would help me understand your point? My philosophy in general would be: don't do stuff you don't need to do until you absolutely can't live without it. If and when you really do need your touch sensor value to be 0 or 1 it is extremely simple to get a 1 from a non-zero value.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by mattallen37 »

Thanks for the information. I don't know why I was having the issue with something like if(sensors&0x08) but I know it wasn't working properly before. Maybe I made a mistake somewhere else...

Please explain this line:

Code: Select all

float value = t1 ? sqrt(Random(40))*cos(PI)-5*42+Random() : 0;
I don't need to know about all the math, just the concept you are trying to teach me. What is the "?" and ":" for? How would I use it for something practical?
For example, what would this line do?

Code: Select all

float value = t1 ? Random() : 0;
I can't think of any examples now, but I know I have used "boolean" sensor values in a math equation before. And a 0 could be useful, maybe not with multiplication though. Here is a lame example of something like I might do.

Code: Select all

//...Set the sensor ports to touch, bool...
sensors=(SENSOR_1*8)+(SENSOR_2*4)+(SENSOR_3*2)+(SENSOR_4*1);
If the value was anything but 0 or 1, it wouldn't work right.

I don't have the HT touch mux anyhow, but there ARE cases that a 1 or 0 would be desirable.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by HaWe »

John, I can't test your code again right now but will report ASAP.

the code I've been using so far is just the original HT code:

Code: Select all

    if(switches&8) switch4=1; else switch4=0;
    if(switches&4) switch3=1; else switch3=0;
    if(switches&2) switch2=1; else switch2=0;
    if(switches&1) switch1=1; else switch1=0;
I just replaced their if/else by ?: and replaced their single variables by an array which is more rational to me.
On the other hand, I don't understand asm code at all.
Unfortunately the HT company provides no better driver code on their HP (actually only a code snippet, not a complete driver), and as I wrote, it still was only a workaround (though I don't see why or when these if statements ever will be execution-time-sensitive).
Additionally I think it's better to have well-defined 1 or 0 states instead of "true" and false, because C has no boolean datatype and "true" is in C code not (German: eineindeutig ≡ bijective) well-defined.

Edit: Indeed I have to calculate with touch sensor states because they are passed as values (0 or 1) to the input layer of a Neural Net (beside other values of other sensors, e.g. distance sensors). https://sourceforge.net/apps/phpbb/mind ... al+net#p59
Image
BTW, I still think it's better to have 1 universal function to read all specified sensors and which will work both for single and for multiple returned values.
As NXC functions can't return values by pointers like
int * value
or
int * values[]
then it might be possible to use references like
void SensorValue(byte port, int & values[])
So having once defined

Code: Select all

SetSensor(S1, SensorUS);    
SetSensor(S2, HTTouchMux);  
SetSensor(S3, HTColor2act); 
it will be sufficient to read their sensor values by

Code: Select all

int myvalue, myarray[];
SensorValue(S1, myvalue);  // 1-dim, but works also with myarray[]
SensorValue(S2, myarray);  // 4-dim: switches 1-4
SensorValue(S3, myarray);  // 5-dim: cnum,R,G,B,W
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by HaWe »

indeed - I had different sensor ports defined in SetSensor and ReadSensor :oops:
Because only the "pressed" status is shown and not the "released" status the screen always remained empty :oops: :oops:
(I changed the program a bit for displaying the switches)

Code: Select all

    task main()
    {
      byte t1, t2, t3, t4;
      SetSensorTouch(S1);
      while (true) {
        ReadSensorHTTouchMultiplexer(S1, t1, t2, t3, t4);
        if (t1)
          TextOut(0, LCD_LINE1, "1 pressed" );
        else
          TextOut(0, LCD_LINE1, "1        " );
        if (t2)
          TextOut(0, LCD_LINE2, "2 pressed" );
        else
          TextOut(0, LCD_LINE2, "2        " );
        if (t3)
          TextOut(0, LCD_LINE3, "3 pressed" );
        else
          TextOut(0, LCD_LINE3, "3        " );
        if (t4)
          TextOut(0, LCD_LINE4, "4 pressed" );
        else
          TextOut(0, LCD_LINE4, "4        " );
      }
    }
Using Numout in your code for the values itself of course they show different values of each single sensor:

Code: Select all

    task main()
        {
          byte t1, t2, t3, t4;
          SetSensorTouch(S1);
          while (true) {
            ReadSensorHTTouchMultiplexer(S1, t1, t2, t3, t4);
        //print edited
            TextOut(0, LCD_LINE1, "sw1="); NumOut(70, LCD_LINE1, t1 );
            TextOut(0, LCD_LINE2, "sw2="); NumOut(70, LCD_LINE2, t2 );
            TextOut(0, LCD_LINE3, "sw3="); NumOut(70, LCD_LINE3, t3 );
            TextOut(0, LCD_LINE4, "sw4="); NumOut(70, LCD_LINE4, t4 );

          }
        }
As I said earlier, 0/1 would be more rational and more useful for calculations -
edit: I simplified my "workaround" a bit, now it's more compact and probably 1ns faster ;)

Code: Select all

#define printf2( _x, _y, _format1, _format2, _value1, _value2) { \
  string sval1 = FormatNum(_format1, _value1); \
  string sval2 = FormatNum(_format2, _value2); \
  string s =sval1+sval2; \
  TextOut(_x, _y, s); \
}

void HTTouchMuxValue(byte port, int & _t[]) {
    long switches, value;

    value=1023-SensorRaw(S2);
    switches=339*value;
    switches/=1023-value;
    switches+=5;
    switches/=10;

    _t[3]=((switches&8)==8);
    _t[2]=((switches&4)==4);
    _t[1]=((switches&2)==2);
    _t[0]=((switches&1)==1);
}


task main(){

  int  sw[4];

  SetSensor(S2, SENSOR_TOUCH);

  while (true) {
    HTTouchMuxValue(S2, sw);

    for (int i=0; i<4; i++)  // that's why I prefer to use arrays...:
      printf2(0,40-(8*i), "switch%d="," %d", i+1, sw[i]);

  }
}
Last edited by HaWe on 29 Mar 2011, 10:17, edited 2 times in total.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by afanofosc »

If you really need an array then your best bet would be to put the values in the array using ArrayBuild. If and when you really need a 0 or a 1 from the values returned by ReadSensorHTTouchMultiplexer then use code like this:

Code: Select all

SomeFunctionThatWantsBooleanInputs(t1!=0, t2!=0, t3!=0, t4!=0)
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by HaWe »

thank you John, I'll think about using your code (5-6 lines)

Code: Select all

ReadSensorHTTouchMultiplexer(S1, t1, t2, t3, t4);
SomeFunctionThatWantsBooleanInputs(t1!=0, t2!=0, t3!=0, t4!=0);
// still something to add here ...? Probably MyFunctionThatWantsAnArrayInsteadOfAChunkkOfSingleValues instead, see below!
sw[0]=t1;
sw[1]=t2;
sw[2]=t3;
sw[3]=t4; // I try to avoid "ArrayBuild" because it's no legal C code
MyFunctionThatWantsArraysInsteadOfAChunkkOfSingleValues(sw);
or just my own one (1 line)

Code: Select all

HTTouchMuxValue(S1, sw);
Just from overviewing, I assume that with my code I will have less letters to write - and probably it's also no waste of time this time... ;)
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by afanofosc »

ArrayBuild is an API function that the NXC library provides. You could write an equivalent for use in a C program intended for another platform. It would make more sense to do that since the C version would be way more optimal than array manipulation in NXC than to avoid using it in NXC for the mistaken belief that it is "not legal C code". No, function calls are legal C code.

You are, of course, completely free to do whatever you wish. The code below gives some insight into the differences between the two approaches.

Code: Select all

/*
subroutine HTTouchMuxValue
	set __signed_stack_001HTTouchMuxValue, 1023
	getin __D0HTTouchMuxValue, __constVal1, 2
	sub __HTTouchMuxValue_7qG2_value_7qG2_000, __signed_stack_001HTTouchMuxValue, __D0HTTouchMuxValue
	mul __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal339, __HTTouchMuxValue_7qG2_value_7qG2_000
	sub __D0HTTouchMuxValue, __constVal1023, __HTTouchMuxValue_7qG2_value_7qG2_000
	div __HTTouchMuxValue_7qG2_switches_7qG2_000, __HTTouchMuxValue_7qG2_switches_7qG2_000, __D0HTTouchMuxValue
	add __HTTouchMuxValue_7qG2_switches_7qG2_000, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal5
	div __HTTouchMuxValue_7qG2_switches_7qG2_000, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal10
	set __signed_stack_001HTTouchMuxValue, 3
	and __signed_stack_002HTTouchMuxValue, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal8
	set __D0HTTouchMuxValue, 8
	cmp 4, __zfHTTouchMuxValue, __signed_stack_002HTTouchMuxValue, __D0HTTouchMuxValue
	mov __D0HTTouchMuxValue, __zfHTTouchMuxValue
	replace __HTTouchMuxValue_7qG2__t_7qG2_000, __HTTouchMuxValue_7qG2__t_7qG2_000, __signed_stack_001HTTouchMuxValue, __D0HTTouchMuxValue
	set __signed_stack_001HTTouchMuxValue, 2
	and __signed_stack_002HTTouchMuxValue, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal4
	set __D0HTTouchMuxValue, 4
	cmp 4, __zfHTTouchMuxValue, __signed_stack_002HTTouchMuxValue, __D0HTTouchMuxValue
	mov __D0HTTouchMuxValue, __zfHTTouchMuxValue
	replace __HTTouchMuxValue_7qG2__t_7qG2_000, __HTTouchMuxValue_7qG2__t_7qG2_000, __signed_stack_001HTTouchMuxValue, __D0HTTouchMuxValue
	set __signed_stack_001HTTouchMuxValue, 1
	and __signed_stack_002HTTouchMuxValue, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal2
	set __D0HTTouchMuxValue, 2
	cmp 4, __zfHTTouchMuxValue, __signed_stack_002HTTouchMuxValue, __D0HTTouchMuxValue
	mov __D0HTTouchMuxValue, __zfHTTouchMuxValue
	replace __HTTouchMuxValue_7qG2__t_7qG2_000, __HTTouchMuxValue_7qG2__t_7qG2_000, __signed_stack_001HTTouchMuxValue, __D0HTTouchMuxValue
	set __signed_stack_001HTTouchMuxValue, 0
	and __signed_stack_002HTTouchMuxValue, __HTTouchMuxValue_7qG2_switches_7qG2_000, __constVal1
	set __D0HTTouchMuxValue, 1
	cmp 4, __zfHTTouchMuxValue, __signed_stack_002HTTouchMuxValue, __D0HTTouchMuxValue
	mov __D0HTTouchMuxValue, __zfHTTouchMuxValue
	replace __HTTouchMuxValue_7qG2__t_7qG2_000, __HTTouchMuxValue_7qG2__t_7qG2_000, __signed_stack_001HTTouchMuxValue, __D0HTTouchMuxValue
	subret __HTTouchMuxValue_return
ends
*/
void HTTouchMuxValue(byte port, int & _t[]) {
    long switches, value;

    value=1023-SensorRaw(S2);
    switches=339*value;
    switches/=1023-value;
    switches+=5;
    switches/=10;

    _t[3]=((switches&8)==8);
    _t[2]=((switches&4)==4);
    _t[1]=((switches&2)==2);
    _t[0]=((switches&1)==1);
}

task main()
{
  int t1, t2, t3, t4;
  SetSensorTouch(S1);
  
/*
	getin __HTMplexRaw, __constVal0, 2
	mul __HTMplexScaled, __HTMplexRaw, __constVal339
	sub __HTMplexScaled, __constVal346797, __HTMplexScaled
	div __HTMplexScaled, __HTMplexScaled, __HTMplexRaw
	add __HTMplexScaled, __HTMplexScaled, __constVal5
	div __HTMplexScaled, __HTMplexScaled, __constVal10
	and __main_7qG2_t4_7qG2_000, __HTMplexScaled, __constVal8
	and __main_7qG2_t3_7qG2_000, __HTMplexScaled, __constVal4
	and __main_7qG2_t2_7qG2_000, __HTMplexScaled, __constVal2
	and __main_7qG2_t1_7qG2_000, __HTMplexScaled, __constVal1
*/
  ReadSensorHTTouchMultiplexer(S1, t1, t2, t3, t4);
  
/*
	arrinit __main_7qG2_x_7qG2_000, __constVal0, __constVal4
	set __signed_stack_001main, 0
	mov __D0main, __main_7qG2_t1_7qG2_000
	replace __main_7qG2_x_7qG2_000, __main_7qG2_x_7qG2_000, __signed_stack_001main, __D0main
	set __signed_stack_001main, 1
	mov __D0main, __main_7qG2_t2_7qG2_000
	replace __main_7qG2_x_7qG2_000, __main_7qG2_x_7qG2_000, __signed_stack_001main, __D0main
	set __signed_stack_001main, 2
	mov __D0main, __main_7qG2_t3_7qG2_000
	replace __main_7qG2_x_7qG2_000, __main_7qG2_x_7qG2_000, __signed_stack_001main, __D0main
	set __signed_stack_001main, 3
	mov __D0main, __main_7qG2_t4_7qG2_000
	replace __main_7qG2_x_7qG2_000, __main_7qG2_x_7qG2_000, __signed_stack_001main, __D0main
*/
  int x[4];
  x[0]=t1;
  x[1]=t2;
  x[2]=t3;
  x[3]=t4;

/*
	arrbuild __main_7qG2_y_7qG2_000, __main_7qG2_t1_7qG2_000, __main_7qG2_t2_7qG2_000, __main_7qG2_t3_7qG2_000, __main_7qG2_t4_7qG2_000
*/
  int y[];
  ArrayBuild(y, t1, t2, t3, t4);
  
/*
	arrinit __main_7qG2_z_7qG2_000, __constVal0, __constVal4
	mov __HTTouchMuxValue_7qG2__t_7qG2_000, __main_7qG2_z_7qG2_000
	subcall HTTouchMuxValue, __HTTouchMuxValue_return
	mov __main_7qG2_z_7qG2_000, __HTTouchMuxValue_7qG2__t_7qG2_000
*/
  int z[4];
  HTTouchMuxValue(S1, z);

  // this code is only here to keep the compiler from optimizing out variables
  NumOut(0, LCD_LINE1, t1);
  NumOut(0, LCD_LINE2, t2);
  NumOut(0, LCD_LINE3, t3);
  NumOut(0, LCD_LINE4, t4);
  NumOut(0, LCD_LINE5, y[0]);
  NumOut(0, LCD_LINE6, z[0]);
}
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: HT TouchMux Sensor gives faulty readings

Post by HaWe »

thank you for contributing and for your efforts to teach me :)
Of course you're right, function calls are legal C code - I have made ​​myself misunderstood. What I actually meant was simply, it's no function that is widly used or provided in a standard C lib (AFAIK).

re: reading mux values:
Your asm Code seems to have LOT less lines of asm code than mine.
Fifteen - Love.
My Code has a LOT less lines of accessing the 1/0 values of the touch mux (if once established in a header file and #included).
Fifteen all :P
Your Code is probably really faster than mine (run time, execution time).
Thirty - Fifteen.
I like the readability and the compactness and the normalized output values of my sensor read function more, and I have less to write (faster development time) ;)
Thirty all.

An even match... :)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest