Search the Community
Showing results for tags 'greater than'.
Found 1 result
-
Hey there guys. First post in a long time. I find myself developing once again on an MSP430G2553 chip on a Rev 1.4 Launchpad and I am trying to take samples from the on-chip ADCs using Energia. It's not secret that the on-chip ADCs are quite unstable (very accurate perhaps?), I don't get anywhere near the kind of jitter I see when using the MCP3008 (10-bit, 8-channel ADC converter IC). Regardless, I am very frustrated with the section of my code that deals with smoothing the signal from analog controls. I am sampling 4 ADC values and averaging it, no problem. What really frustrates me is that when I try to check if the new value is within a certain sensitivity (range) of the last recorded value, I have to do a strange work-around or else I get constant resends as if I'm not even checking if the value is in the certain range. In other words, I cannot use the compare operators greater than, less than, greater than/equal to, and less than/equal to, in order to check if the new ADC value is within a certain range of the old recorded value. To illustrate this, I will include the code I use to do this and show you what I would like to do (which doesn't work) and what I do currently (which still results in some glitches) Just for reference, this is what the Control class looks like: class Control { public: //Identification information int pin; //Sets the pin to be used by the control int ID; //Identification number (0-31) //Data processing variables int value; //Stores the current value int oldValue; //Stores the old value (for preventing constant resends) int counter; //Counter used for averaging int average; //Value use for calculating average int sensitivity; //Value used for setting sensitivity (a variable in smoothing algorithm) @todo //Constructor Control(int nID, int nPin, int nSensitivity); //Methods int Read(void); //Reads the value of the control boolean isNew(void); //Returns true if the value has updated (within a reasonable range, the sensitivity) void Send(void); //Transmits the control change to the computer for processing }; And this is what the Control.Read() function does (it includes the average code) int Control::Read(void) { int pinVal = analogRead(pin); if(pinVal == 1023 || pinVal == 0) //it is max/min { return pinVal; //I do this so that mins/maxs can be sent anyway. It's important that absolute mins/maxs are sent. } if(counter != 3) //Averaging counter that's stored on the class { average += analogRead(pin); counter++; //Increment Counter return 1025; //Not ready value (outside ADC range) } else { average /= 4; //Divide by 4 to average counter = 0; //Reset counter return average; } } } Code that I would like to use: boolean Control::isNew(void) { value = Read(); //Set value of control if(value == 1025) //Not ready return false; //First check for maxs/mins (to prevent resending) if(value == 1023 || value == 0) //it is max/min { if(value != oldValue) //max/min was not sent already { oldValue = value; return true; } } //Check if its within sensitivity setting if(value >= (oldValue-sensitivity) || value <= (oldValue+sensitivity)) //This does nothing to smooth input (constantly returns true, even when it shouldn't) return false; //Still within sensitivity, report false else { oldValue = value; //It's changed more than the sensitivity, update values and report true return true; } } return false; //If it hasn't returned true by now, return false } Code that I use right now... boolean Control::isNew(void) { value = Read(); //Set value of control if(value == 1025) //Not ready return false; //First check for maxs/mins (to prevent resending) if(value == 1023 || value == 0) //it is max/min { if(value != oldValue) //max/min was not sent already { oldValue = value; return true; } } boolean within5 = false; //Please ignore the irrelevant name of this variable int checkVal = 0; //Then check if it's within 15 of previous value for(int i=0;i<15;i++) { checkVal = value + i; if(checkVal == oldValue) { within5 = true; break; } checkVal = value - i; if(checkVal == oldValue) { within5 = true; break; } } if(!within5) //Not within 15 { oldValue = value; return true; } return false; //If it hasn't returned true by now, return false } The main loop does something like this: if(control_1.isNew()) { control_1.Send(); //Simply prints the value to the serial line } Similarly, I have tried to see if the new ADC value is above a certain threshhold as to count it as a maximum value. Above a certain value (like 1015) the sensitivity check becomes erratic, it sends new values even if they're within (for example) 2 of the last value. The code I used was: if(value > 1015) //If it's above a certain threshhold value = 1023; //Count it as a maximum The kind of output I would get is still like: 1020 1022 1018 1023 1023 1020 The sensitivity is normally set to within 10-20 for the on-board ADC. For controls connected to the MCP3008, the sensitivity is about 5, it is as stable as a rock. What is going on? Why can't I compare these values? Is it related to the type of variable I store the value in? I have tried changing the related variables to unsigned integers and it has no effect. It has had me pulling my hair out. I hate inefficient code on MCUs and using for loops simply to check if a value lies within some range seems pretty inefficient to me. I'll post the finished project when I'm done. Thanks guys!
- 4 replies
-
- analog input
- smoothing
-
(and 5 more)
Tagged with: