help me to write a code pls

i have the following rules and i need to write a code (2 analog inputs ==> 4 digital outputs)…

in1 in2 o1 o2 o3 o4
0 0 0 0 0 0
1 1 1 0 0 0
-1 1 0 1 0 0
0 1 0 0 1 0
-1 -1 1 0 0 1

the problem is when both (in1 & in2 are zeros there is some voltage difference between them about (0.3v) so it need to put threshold in the condition … i need some help pls

How do you get the -ve values?

it is not negative ... it is like (3 high , 2 reference , 1 low) ... three state

It looks like a tri-state decoding. What are the voltages ? What is the reference voltage ? Is it the reference voltage of the Arduino board ? The analog input can read an input of 0...5V.

I would do the decoding with a two-dimensional array, for example decode[3][3]

yes.. it is a tri-state ... state 1 ==> 2.5v state 0 ==> 1v state -1 ==> 0.8v ------------------------but it is not stable so i dont want to depend on the voltage values .... i want to make it according the above table ....

dany151: ... but it is not stable ....

What [u]is[/u] it then?

i mean the reference sometimes shifted up or down .. for example if ref being 2v ==> state1 = 3.5v and state3= 1.8v ...is it clear now?

The difference between 1 and 0.8 is very low.
And it is not clear how they change.
Are you sure those are the voltages ?
Perhaps “-1” is defined as a voltage lower that 0.8 V ?
And “1” as a voltage higher than 2.5 V ?

Is the reference something you can also read with an analog input ?

// Example, not tested, expect a few errors.

// Decode tri-state
// -------------
//   "-1" = index [0]
//   "0" = index [1]
//   "1" = index [2]
//   
//   decode[in2][in1]
//   The data is in hex notation, and order: o4,o3,o2,o1
//   The invalid entries are set to 0xFF

const char *pTriState[] = { "-1", "0", "1" };

const int decode[3][3] = 
{
  {0x09, 0xFF, 0xFF },   // in2 = [0], in1 = [0],[1],[2]
  {0xFF, 0x00, 0xFF },   // in2 = [1]
  {0x02, 0x04, 0x01 },   // in2 = [2]
};

const int pinIn1 = 0;      // analog input
const int pinIn2 = 1;      // analog input
const int pinReference = 2; // analog input
const int pinOut1 = 8;      // digital output
const int pinOut2 = 9;      // digital output
const int pinOut3 = 10;      // digital output
const int pinOut4 = 11;      // digital output

void setup()
{
  Serial.begin( 9600);
  Serial.println( "tri-state decode");
}

void loop()
{
  int d, i, in1, in2;
  
  in1 = readTriState( pinIn1);
  in2 = readTriState( pinIn2);
  
  d = decode[in1][in2];
  
  if( d == 0xFF)
  {
    Serial.println( "Invalid entry");
  }
  else
  {
    for ( i=0; i<4; i++)
    {
     Serial.print( "o");
     Serial.print( i+1);
     Serial.print( " = ")
      if( bitRead( d, i))
      {
        Serial.println( "1");
        // set the digital pin here.
      }
      else
      {
         Serial.println( "1");
         // set the digital pin here.
      }
    }
  }
}

int readTriState( int pin)
{
  int raw;
  float voltage, reference;

  raw = analogRead( pin);
  reference = (float) raw / 1023.0 * 5.0;

  raw = analogRead( pinReference);
  voltage = (float) raw / 1023.0 * 5.0;
  
  Serial.print( "Voltage A");
  Serial.print( pin);
  Serial.print( " = ");
  Serial.println( voltage);

  Serial.print( "Reference Voltage = ");
  Serial.println( reference);

  
  if( voltage < ..... something with reference ....)
    return 0;
  else if( voltage < ..... something else with reference ....)
    return 1;
  else
    return 2;
}

Writing this code makes me feel like I’m back in school. Is this an assignment for school ?

You have to split the problem into smaller parts.
The function readTriState() controls the analog input and returns an 0,1 or 2. The 0,1,2 stand for “-1”, “0” and “1”.
The decode array is the translation for the outputs. If it is hard to understand, write all the one’s and zero’s on paper if you have to.
Writing the digital pins should be added, perhaps an array with the output pins can be used for that.

dear it is not for school … its a project below is the signal from scope with some explaintion … i want to write a code for these signals

the problems are 1- conditions 2 & 3 are same (but the different in shape as seen in the figure) 2- the reference at 1v is not same for both signals, also it shifted over 1v or lower than 1 v for both signals together.so that i cant depent on the values shown in the figure ...

so i dicided to make the conditions according the signal shape and Behavior

Thanks for the picture, that picture is worth more than 1000 words.

What is the difference between the left and the right ? Is that the same signal, how much time is between it ? If the middle (the not active) voltage is shifting, perhaps it should be determined continuously.

Is that signal changing only twice a second or so ? Is it that slow ? Could you add a filter to the inputs. For example 4k7 resistor to the analog input, and a capacitor of 1nF or 10nF to ground (the capacitor 'after' the resistor at the analog input).

I think it can be done, but it will not be easy. The spikes are a problem. So there should be averaging of some samples in software. I think the sketch should keep track of the middle (not active) voltage and the high level and low level. That are 6 voltages which can change.

I don't know if there is a standard mathematical solution for this. I do know that with such rough signals, the area of a peak is calculated. If the area is large enough, it is considered valid.

i must thank u dear for your interest …they just 2 inputs i captured 2 times …each picture show 2 conditions …also this signals are filterd and shifted to be (0 - 5)v … according to arduino analog inputs

The problem is not the decoding of the tri-state to outputs (see my example code), but to recognize the very noisy input signal.

I'm sorry, but I don't know how to help. If I had such a signal myself, I could do some tests with filtering and calculation the area of the peaks.

If no one else replies in a few days, you could start a new topic with a better title: Reading tri-state in a very noisy signal. If you do, also add a link to this thread. And perhaps you could tell where this signal comes from. Perhaps you can make a better signal at the source of it. (It looks like a rotation encoder that is transmitted wireless).

If you can sample the signal fast enough to get a few samples per cycle (so it is high for three reads, say, then low for 3 or 4 etc) I see a few characteristics in your plots that might help.

First the key thing seems to be the difference (or lack of it) between the two signals - simply subtracting the values should pick that out even if the absolute size of the values varies.

If you want a different result when the two values are similar but low rather than similar but high that should be easy to detect because a rough threshold is probably OK. Alternatively you could monitor a succession of values for a change of direction - the difference between successive samples rather than the absolute value.

And if you are only concerned with the major variations rather than the very minor jitter you could keep a running average of (say) the most recent three samples.

...R

thnx .... Erdin ....i will try to enhance my signal or wirte a code and test ....

dear .....Robin2....i will try to write a code ...

Thinking about this overnight I think you will need to be able to sample at a much faster rate than the signal frequency if you are to deal with the noise.

I suspect my earlier concept of 3 or 4 samples per cycle may not be enough. My feeling is that the sampling rate would need to be fast enough to capture about 10 values in the period while one of the signals is high (or low, etc). That would mean sampling at about 20 times the signal frequency - and may be beyond the capability of a microprocessor.

That way you could have a moving average of 6 values and be certain that at the appropriate time in the cycle all of those samples could come from a high signal.

I don't think you said whether you need to do this in real time on a continuous basis or whether you just want to analyse a signal that has been captured.

It would be interesting to know what signal frequency you are working with.

...R

dear Robin2 i write a code yesterday night … depending on calibration example of IDE library …(analog examples )… see it below

first the calibration example

/*
Calibration

Demonstrates one technique for calibrating sensor input. The
sensor readings during the first five seconds of the sketch
execution define the minimum and maximum of expected values
attached to the sensor pin.

The sensor minimum and maximum initial values may seem backwards.
Initially, you set the minimum high and listen for anything
lower, saving it as the new minimum. Likewise, you set the
maximum low and listen for anything higher as the new maximum.

The circuit:

  • Analog sensor (potentiometer will do) attached to analog input 0
  • LED attached from digital pin 9 to ground

created 29 Oct 2008
By David A Mellis
modified 30 Aug 2011
By Tom Igoe

http://arduino.cc/en/Tutorial/Calibration

This example code is in the public domain.

*/

// These constants won’t change:
const int sensorPin = A0; // pin that the sensor is attached to
const int ledPin = 9; // pin that the LED is attached to

// variables:
int sensorValue = 0; // the sensor value
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value

void setup() {
// turn on LED to signal the start of the calibration period:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);

// calibrate during the first five seconds
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);

// record the maximum sensor value
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}

// record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}

// signal the end of the calibration period
digitalWrite(13, LOW);
}

void loop() {
// read the sensor:
sensorValue = analogRead(sensorPin);

// apply the calibration to the sensor reading
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

// in case the sensor value is outside the range seen during calibration
sensorValue = constrain(sensorValue, 0, 255);

// fade the LED using the calibrated value:
analogWrite(ledPin, sensorValue);
}

second is my code

int f1 = A0;
int f2 = A1;
int right = 3;
int left = 6;
int forward = 8;
int back = 10;
int value1= 0;
int min1=1023;
int max1=0;
int value2= 0;
int min2=1023;
int max2=0;
int x = 1;
void setup () {
Serial.begin(9600);
pinMode(right, OUTPUT);
pinMode(left, OUTPUT);
pinMode(forward, OUTPUT);
pinMode(back, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
while (millis() < 2) {
value1 = analogRead(f1);
value2 = analogRead(f2);
if (value1 > max1) {
max1 = value1;
}
if (value2 > max2) {
max2 = value2;
}
if (value1 < min1) {
min1 = value1;
}
if (value2 < min2) {
min2 = value2;
}
}

digitalWrite(13, LOW);
Serial.println(“min1”);
Serial.println(min1);
Serial.println(“max1”);
Serial.println(max1);
Serial.println(“min2”);
Serial.println(min2);
Serial.println(“max2”);
Serial.println(max2);

}
void loop () {
while(x>0) {
value1=analogRead(f1); //value= 1024 * voltage / 5
value2=analogRead(f2); //value= 1024 * voltage / 5
Serial.println(“value1=”);
Serial.println(value1);
Serial.println(“value2=”);
Serial.println(value2);
if (value1 >= max1 && value2 < max2 ) {
digitalWrite(forward,HIGH);
digitalWrite(back,LOW);
digitalWrite(left,LOW);
digitalWrite(right,LOW);
break;
}
if (value1 <= min1 && value2 - value1 <= 0.15) {
digitalWrite(forward,LOW);
digitalWrite(back,HIGH);
digitalWrite(left,LOW);
digitalWrite(right,LOW);
break;
}
else if (value2 >= max2 && value2 - value1 >= 2) {
digitalWrite(forward,LOW);
digitalWrite(back,LOW);
digitalWrite(left,HIGH);
digitalWrite(right,LOW);
break;
}
else if (value2 <= min2 && value1 > min1) {
digitalWrite(forward,LOW);
digitalWrite(back,LOW);
digitalWrite(left,LOW);
digitalWrite(right,HIGH);
break;
}
else {
digitalWrite(forward,LOW);
digitalWrite(back,LOW);
digitalWrite(left,LOW);
digitalWrite(right,LOW);
break;
}
}
delay(20);
}

check it pls …

I haven't checked the logic of your program but I don't think it will work properly because you are relying on a single sample from each pin and. There is a finite time between successive samples so you may be getting samples from two different phases of the cycle. Also you need to deal with the possibility that a noisy low spike on a high signal may be the same as a noisy high spike on a middle signal.

Calibration may be necessary and desirable but I don't think it's the principal requirement.

You still haven't said what is the frequency or cycle duration of the signal you are sampling.

I also think it will help the decision-making logic if you first convert the samples to a standard value that represents their logical value - e.g. 1,2, 4, 8, 16, 32. Using powers of 2 will probably simplify comparisons. Using standard values also separates your logic code from any changes that may be needed in the sampling code.

At the risk of "teaching granny to suck eggs" I mean that you should take a few samples of each pin in the order ABABABABAB and then average the A's and the B's to decide the "value" of the sample. You should then decide whether the value should be considered low, middle or high and, if pinA is low store it as 1, if middle, store it as 2 and if high store it as 4. For pinB you should use the values 8, 16 and 32 to prevent confusion. Then your "logic" will be comparing the value of pinA(which will be 1,2 or 4) with pinB (which will be 8,16 or 32). If you now add the resulting values (pinA + pinB) you will get one of 9 separate values and you can set your outputs accordingly.

...R

You still haven’t said what is the frequency or cycle duration of the signal you are sampling.

the signal is not periodically … i got it from sensors…it is form EOG sensor read this