How to count peaks multiple times? - arduino

I am opening a valve to let fluid flow. The pressure being measured here is with how much pressure the fluid is being pulled into a system. I am trying to measure the average value of only first 10 Pdiff (PMax-PMin). once the average value is calculated, the valve is closed.
And based on this average value, the valve will again open and close for 1 peak, and then for 2 peaks, and for 3 peaks and so on. I am storing the pressure value in an array and comparing the value with its before and after value, I get max and min values.

You increment your peakcounter using ++peakcounter but then immediately set peakcounter=0 in the if block of if(peakcounter==0)
Since you reset your peakcounter, you never get to peakcounter == 2
if ( valstate == false && Pdelta >= average)
{
{
++peakcounter; // keeps the count of how many times the value has gone
above average
}
// Checks for the number of times and then performs action
if (peakcounter == 1) {
digitalWrite(4, HIGH);
startTime = millis();
valstate = true;
peakcounter = 0; //the offending line
}
What you need to do the following (Note: code is not optimized. I don't fully understand what you need, but this should fix the issue you wrote about)
int currentMax = 0;
// your code here....
if ( valstate == false && Pdelta >= average){
++peakcounter;
if(peakcounter > currentMax){
// Checks for the number of times and then performs action
if (peakcounter == 1) {
digitalWrite(4, HIGH);
startTime = millis();
valstate = true;
peakcounter = 0;
currentMax++;
}
//the rest of your peakcount checking code here
}

Related

Arduino Loop not recognizing break condition?

I currently have a nested for loop system that is writing commands to a motor and reading from the attached encoder. For some reason, the program will not break out of the loop using the conditional. I have used some print statements to debug a little and it clearly recognizes that PWMcount is greater than 76 as it prints as far as I will let it count. Any advice is much appreciated, Thank You!
for(int PWMcount = 58;PWMcount < 76;) { //10-20 RAMP
for (int counter = 1; counter < 4;) {
if (counter != 3) {
finalTime = millis();
float newPos;
newPos = encoder.read();
if (newPos != oldPos) {
deltaTime = (finalTime - initialTime);
deltaPos = (newPos-oldPos);
oldPos = newPos;
initialTime = finalTime;
//Serial.println(deltaPos/deltaTime);
}
counter = counter+1;
delay(100);
// Serial.println(PWMcount);
}
else {
finalTime = millis(); //catches time for beginning of each loop iteration
float newPos;
newPos = encoder.read();
if (newPos != oldPos) { //Checks for encoder movement
deltaTime = (finalTime - initialTime); //calculates deltaT in milliseconds
deltaPos = (newPos-oldPos); //sets change in position from one iteration to the next
oldPos = newPos; //Sets old to new to fail if statement unless movement is detected.
initialTime = finalTime; //sets time at beginning of loop to time of ending last loop in order to correctly calculate deltaT in the next iteration
//Serial.println(deltaPos/deltaTime); //Prints rate of the encoder disk in deg/ms (Confirmed by manually taking data and seeing that 1 Rotation outputs values from 0-360
}
counter = 1;
PWMcount=PWMcount+1;
analogWrite(RPWM_Output, PWMcount); // Increases Motor PWM in accordance to loop
}
Serial.println(PWMcount); // UNCOMMENT TO TROUBLESHOOT PWM
delay(100);
}
}
This for loop never completes:
for (int counter = 1; counter < 4;)
The body of the loop is a single if statement. On the last iteration of the loop, the else branch is taken, and that branch sets the loop variable counter back to 1, so the expression counter < 4 is always true, and so that loop never exits.
Since it never exits, the code never gets to a point where the outer loop conditional is tested, nor where the outer loop would ever branch back to the beginning at all.
One possible way to fix the situation would be to combine the two loop conditions, making it a single loop:
for(int PWMcount = 58, counter = 1; PWMcount < 76;) { //10-20 RAMP
if (counter != 3) {
finalTime = millis();
float newPos;
newPos = encoder.read();
if (newPos != oldPos) {
deltaTime = (finalTime - initialTime);
deltaPos = (newPos-oldPos);
oldPos = newPos;
initialTime = finalTime;
//Serial.println(deltaPos/deltaTime);
}
counter = counter+1;
delay(100);
// Serial.println(PWMcount);
}
else {
finalTime = millis(); //catches time for beginning of each loop iteration
float newPos;
newPos = encoder.read();
if (newPos != oldPos) { //Checks for encoder movement
deltaTime = (finalTime - initialTime); //calculates deltaT in milliseconds
deltaPos = (newPos-oldPos); //sets change in position from one iteration to the next
oldPos = newPos; //Sets old to new to fail if statement unless movement is detected.
initialTime = finalTime; //sets time at beginning of loop to time of ending last loop in order to correctly calculate deltaT in the next iteration
//Serial.println(deltaPos/deltaTime); //Prints rate of the encoder disk in deg/ms (Confirmed by manually taking data and seeing that 1 Rotation outputs values from 0-360
}
counter = 1;
PWMcount=PWMcount+1;
analogWrite(RPWM_Output, PWMcount); // Increases Motor PWM in accordance to loop
Serial.println(PWMcount); // UNCOMMENT TO TROUBLESHOOT PWM
delay(100);
}
}
A couple of notes:
The loop condition does not bother to check the counter value, because the loop body obviates the comparison. The counter variable is always less than 4.
I moved the last two lines of the outer loop into the else branch of the if statement. They never executed in your original code, so maybe you just want to remove them altogether. But if the intent was to execute those two lines each line the inner loop reached its end (i.e. counter is 3), then this change matches that intent.

Want the numbers in between two limits with equal time interval

I try to get values in between 10 and 100 so I arrange
int pos;
long previousTime =0;
int increment = 1;
int interval = 10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
long currentTime = millis();
if(currentTime - previousTime > interval){
previousTime = currentTime;
pos +=increment;
if(pos<= 10 || pos > 100){
increment = -increment;
}
Serial.println(pos);
}
}
But my output showing only 1 and 0.If I reduce lower limit into 0 or 1 then I got values in between those limit values given inside the if statement but not getting proper result when I increase the lower limit.Why?
Ok your problem is simple now that we can see the whole code. Look at position, it starts out at 0. On the first pass through loop it gets increments to 1. Then that if statement checks and 1 is indeed less than 10 so it makes increment -1. Then on the next pass through loop that gets added making pos 0 again and since 0 is less than 10 it reverses increment again. It’s doing exactly what you told it.
Try starting pos out at the 10 and see what happens.
If it's not trivial to you, here a suggestion
int pos=0;
unsigned long previousTime =0;
int increment = 1;
int interval = 10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
unsigned long currentTime = millis();
if(currentTime - previousTime >= interval){
previousTime = currentTime;
pos += increment;
if(pos <= 10) increment = 1;
if(pos >= 100) increment = -1;
// else leave increment as is ...
Serial.println(pos);
}
}

CRGFLG register, last bit not getting set

I'm using a FreeScale 9S12C micro controller and am coding in Code Warrior. I'm trying to create a SEQ detector for Sequence 10011. When I do a simulation the program gets stuck in the function DelayGate, everything else appears ok. It seems that the last bit in the CRGFLG register is never getting set like it's supposed to. I believe it's supposed to get set at the end of every real time clock cycle. I set RTICTL = 0b01000000, so the real time clock should have a period of 1.024 ms. So my expected behavior is that the program should stay in the DelayGate for approximately 1.024 ms and than exit, but the program stays in delay gate for ever and never exits. It appears that the last bit in CRGFLG never gets set for some reason, and I'm not sure why. Thanks for any help anyone can provide me! Here's my code. I'm using a 8 MHz crystal.
// Constants
#define CRYSTAL_CLOCK_FREQ 8000000L //set the clock to 8 MHz?
#define LED_COUNT_MAX 488 //(500 ms)/(1.024 ms) about 488
// Includes
#include <hidef.h> /* common defines & macros */
#include "derivative.h" /* derivative-specific */
// Prototypes
void SysInit(void);
void UpdateLED(void);
int input;
int state;
int nn = 5;
int value;
void Delay(int nn);
int UpdateStatetask(int input, int state);
void DelayGate(void);
int BeepFlag = 0;
int done = 0;
#endif
/*****************************************************
* main - Program main
****************************************************/
void main(void){
COPCTL = 0x00; // Disable the COP timer
RTICTL = 0b01000000; //8 MHz crystal, period of real time clock is 1.024 ms
PTT = 0x00; // initally all logical zero
DDRT = 0b11111100; // PT0 "0" input
//PT1 "1" input
//PT2 SEQ state 1 indication
// PT3 SEQ state 2 indication
// PT4 SEQ state 3 indicaiton
// PT5 SEQ state 4 indication
// PT6 SEQ detection
// PT7 LED Clock
PERT = 0b11111111; // enable pulling on all port T
PPST = 0b11111111; // pull-down to ground all port T
CLKSEL = 0x00;
PLLCTL = 0x00;
CRGINT = 0b10000000;
while (1){
UpdateLED();
DelayGate();
}
}
/**************************************************
* UpdateLED()
* When the LED count runs out, toggle and beep
*************************************************/
void UpdateLED(void){
static int state = 0;
int input;
int LedCount = LED_COUNT_MAX; //488*1.024 ms = 0.4997 s
if (--LedCount == 0){ //decrement LED count
LedCount = LED_COUNT_MAX;
PTT = 0b10000000; //turn on LED clock
}
if (PTT & 0x01 == 1){ //bitwise and, checking for clock LED
if(PTT & 0b00000001){ //"0" input
input = 0;
}
if(PTT & 0b00000010){ //"1" input
input = 1;
}
}
UpdateStatetask(input,state);
}
/**************************************************
* UpdateStatetask()
*************************************************/
int UpdateStatetask(input, state){
switch(state){
case 0:
PTT = 0b00000000; //state 0 no LEDs should light up
if (input == 0){ //SEQ = 10011
state = 0; //if "0" is entered at state zero stay at state zero
}
else if(input == 1){
state = 1; //if "1" is entered at state zero go to state 1
}
break;
case 1:
PTT = 0b00000100; //turn on LED indicating state 1
if (input == 0){ //if "0" is entered at state one go to state two
state = 2;
}
else if(input == 1){ //if "1" is entered at state one stay at state one
state = 1;
}
break;
case 2:
PTT ^= 0b00001100; //state 2 indication turn on 2 LED
if (input == 0){ //if "0" is entered at state two go to state three
state = 3;
}
else if(input == 1){ //if "1" is entered at state two go to state one
state = 1;
}
break;
case 3:
PTT = 0b00011100; //state 3 indication turn on 3 LED
if (input == 0){ //if "0" is entered at state three go to state zero
state = 0;
}
else if(input == 1){ //if "1" is entered at state three go to state four
state = 4;
}
break;
case 4:
PTT = 0b00111100; //state 4 indication turn on 4 LED
if (input == 0){ //if "0" is entered at state four go to state 2
state = 2;
}
else if(input == 1){//if "1" is entered at state four go to state 1
PTT = 0b01111100; //SEQ detection turn on 5 LED
state = 1;
}
break;
default:
state = 0;
break;
}
return state;
}
/**************************************************
* DelayGate
* Wait for timeout, then restart the RTI clock
*************************************************/
void DelayGate(void){
while ( (CRGFLG & 0x80) == 0){
;
}
CRGFLG = 0x80;
}
When I compile the only warnings I get is that
result of function call is ignored on this line: UpdateStatetask(input,state)
This is the old style of function call here on this line: int UpdateStatetask(input, state){
These warnings shouldn't cause the problem I'm having. Thanks for any help!

Using spreadsheet to count consecutive cells

So I want to use Google spreadsheet to find how many times does five consecutive cells have a value greater than a given value in a row,but one cell cant be a part of two set of consecutive cells.For example i want to count the number of times a particular item was bought in a month for consecutive five days but if it was bought for 7 days at a stretch it will only be counted as one whereas if it is multiple of five it will be counted as many multiples of five.
For Ex:If cells 1-5 have a value greater than the given value it should give me a count of 1, but if cells 1-9 also are greater than the given value even then it should give me count of 1 but if 1-10 have a value greater than the given value then it should give me a count of 2.I hope this was clear.
I want to write this code in Google Drive using custom function, I tried writing a code in C.
*
int x; //no. of rows
int y; //no. of columns
int arr[x][y]; //array to store numbers
int count[x];
int i,j,k; //for loops
for(i=0;i<x;i++) //set count to 0 for all rows
count[x]=0;
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
{
for(k=1;k<=5, j<y;k++, j++)
{
if(!arr[i][j]>0)
{
break;
}
else if(k==5 && arr[i][j]!<1)
{
count[i]++;
j--;
}
}
}
}
//display the count array now to see result.
*
You can do this without writing code. That's kinda the purpose of a spreadsheet.
You have one column, say column A, with the values.
In the next column, start a counter that increments each row if the value in the first column is >= your preset value, and reset the counter if not. The formula would be something like (for cell B2)
=IF(A2>=$E$1,B1+1,0)
In the next column, calculate the multiples of 5. For cell C2:
=IF(MOD(B2,5)=0,C1+1,C1)
Copy those cells down to the bottom of the list in column A, and the last value will be the count of values that exceeded cell $e1 a multiple of 5 consecutive times.
Another way using native Sheets functions:
=ArrayFormula((ROWS(A:A)-LEN(REGEXREPLACE(CONCATENATE(LEFT(A:A>=1)),"TTTTT","")))/5)
and using a custom function:
function countGroups(range, comparisonValue, groupSize) {
var v = comparisonValue || 1; // default to comparing to 1 if not specified
var n = groupSize || 5; // default to groups of 5 if not specified
var count = 0, counter = 0;
for (var i = 0, length = range.length; i < length; i++) {
if (range[i][0] >= v) {
counter++;
if (counter == n) {
counter = 0;
count++;
}
}
else
counter = 0;
}
return count;
}

Having incrementing problems in Arduino code

Basically I am reading raw values from an accelerometer (i.e these values change in response to gravity and acceleration).
I have set a range of values for the raw values(i.e from -100 to 100 instead):
x = map(ax, -2048, 2048, -100, 100 );
now im trying to increment "count" x greater than 50:
if (x>50) {
count++;
}
main example code here:
void loop(){
x = map(ax, -2048, 2048, -100, 100 );
if (x>50) {
count++;
}
}
but when I compile the code, x becomes greater than 50 and the count just keeps incrementing and what I want it to do is count 'one by one' only when the value becomes greater than 50 seen as the values change as accelerometer moves?
I think you want to count how many times you measure a value over 50. If you check the condition in every loop() iteration, then you will get how many time (measured in loops) the value is over 50.
You need something like this
boolean checked = false;
void loop(){
x = map(ax, -2048, 2048, -100, 100 );
if (x > 50 && !checked) {
count++;
checked = true;
}
if (x < 50 && checked) {
checked = false;
}
}

Resources