Display String Output

Hello!
I am trying to print a conditional statement:


var A_x = msg.payload.d.X;
var A_y = msg.payload.d.Y;
var A_z = msg.payload.d.Z;


var A_r = Math.sqrt(A_x*A_x + A_y*A_y + A_z*A_z);

if (abs( A_r_prev - A_r) > 1100) {
    msg = "Passed";
}

var A_r_prev = A_r;

return msg;

How to I get it to print passed. Also, is this how you store the variable (A_r_prev) and subtract it from the current value?

Hi

Functions must return message objects, not plain values.

Currently, your code sets msg to String "Passed" if the condition is met and returns that. That is not the right way to do it.

You would normally set a property of msg before returning it...

msg.payload = "Passed";
...
return msg;

For storing the value of A_r_prev between calls to the Function, you can use Context to do that - https://nodered.org/docs/user-guide/context

// Get the current value of A_r_prev from flow context - default to 0
// if not already set
var A_r_prev = flow.get("A_r_prev") || 0;

// do your check against it etc


// Update the value in context
flow.set("A_r_prev", A_r_prev);

You'll also need to change the abs(...) call to be Math.abs(...) as abs() isn't a function in JavaScript.

Thank you!

Unfortunately there is no output anymore; here is my updated code


var A_x = msg.payload.d.X;
var A_y = msg.payload.d.Y;
var A_z = msg.payload.d.Z;

var A_r = Math.sqrt(A_x*A_x + A_y*A_y + A_z*A_z);
var A_r_prev = flow.get("A_r_prev") || 0;

flow.set("A_r_prev", A_r_prev);

if ( math.abs(A_r - A_r_prev) > 300) {
    msg.payload = "Passed";

    return msg;
}

I would also like to implement an audio condition (in addition to the absolute value threshold, it must pass an audio decibel level threshold. How do I do that?
Thanks

Step 1 get what you currently have working before you make it more complex.

Look at the Logging Events and handling errors sections of this page from the docs.

https://nodered.org/docs/user-guide/writing-functions

Add lines in your function so you can check what is happening to different variables.

Thanks,
I was able to fix it so that both the mic and the accelerometer is running. However, the mic says NaN
I think it is because the accelerometer variables are still looping through.

I may need to apply some filter. Could you provide some help so that I can get both the microphone level and the accelerometer to run?

currently, the mic has no function but the accelerometer does as printed above with minor changes.

Thanks

we do not mind helping - but you need to contribute - paste up what you have that is working and the expected output and then show where you are stuck

Craig

Ok, no problem. Here is my current code

var A_x = msg.payload.d.X;
var A_y = msg.payload.d.Y;
var A_z = msg.payload.d.Z;

var A_r = Math.sqrt(A_x*A_x + A_y*A_y + A_z*A_z);
var A_r_prev = context.get("A_r_prev") || 0;

context.set("A_r_prev", A_r);

msg.payload = ""+ Math.abs(A_r - A_r_prev);

// if ((A_r - A_r_prev) > 1000) {
//     msg.payload = "Passed";

    
// }
// else {
//     msg.payload = "Not Passed";
// }


return msg;

This is my state machine that I would like to implement in node red -- it has been coded in C and I do not know how to convert it to javascript and implement it into a function. Please let me know if you can provide any help!

if (*state == 0) {

    	if (abs(glob_prev_r - r) > 2000 && (msTick - *msTickStateChange > keeptime)) {

    	*msTickStateChange = msTick;

    	sprintf(dataOut, "\n\n\r\t\tFirst Movement Detected!\t\t\r\n"

    	);



             *state = 1;

    	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

     }

    }

     else if (*state == 1) {

    	if (abs(glob_prev_r - r) > 2000  && (msTick - *msTickStateChange > keeptime)) {

    	*msTickStateChange = msTick;

    	sprintf(dataOut, "\n\n\r\t\tSecond Movement Detected!!!\t\t\r\n"

    	   	);

    	*state = 2;

    	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	}

    	if (msTick-*msTickStateChange > resettime) {

    	sprintf(dataOut, "\n\n\r\t\tFalse Alarm\t\t\r\n"

    	   	);

    	   	//BSP_LED_On(LED1);

    	            *state = 0;

    	   	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	    }

    	}



     else if ((*state == 2)  && (msTick - *msTickStateChange > keeptime)) {

    	if(msTick-*msTickStateChange > resettime) {

    	*msTickStateChange = msTick;

    	sprintf(dataOut, "\n\n\r\t\tFalse Alarm\t\t\r\n");

      *state = 1;

    	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	}

    	else if (abs(glob_prev_r - r) > 2000 && (msTick - *msTickStateChange > keeptime)) {

    	*msTickStateChange = msTick;

    	  sprintf(dataOut, "\n\n\r\t\tSTEALING STEALING STEALING\t\t\r\n");

          *state = 3;

    	   	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	}





     }

     else if ((*state == 3) && (msTick - *msTickStateChange > keeptime)) {

    	if(msTick-*msTickStateChange > resettime) {

    	   	*msTickStateChange = msTick;

    	   	sprintf(dataOut, "\n\n\r\t\tFalse Alarm\t\t\r\n");

          *state = 2;

    	   	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	   	}

    	   	else if (abs(glob_prev_r - r) > 2000 && (msTick - *msTickStateChange > fasttime)) {

    	   	*msTickStateChange = msTick;

    	   	  sprintf(dataOut, "\n\n\r\t\tSTEALING STEALING STEALING\t\t\r\n");

              *state = 3;

    	   	   	CDC_Fill_Buffer((uint8_t *) dataOut, strlen(dataOut));

    	   	}

     }

     glob_prev_r = (int) r;

    }

Thanks

have a look at this FSM node - the author is a regular in here and is very helpful - he has coded heaps of examples also

craig

Thank you, I have read that information and it is very helpful.

One quick question. I am trying to modify the microphone output ( ST imported) in decibels.

With the acceleration, I called x, y, and z using var A_x = msg.payload.d.X etc.

How do I modify/create a variable for microphone decibels?

this is the current code for the microphone

return msg;

all it does is return the decibels; I will need to create thresholds for the values but I need to find out how to create a variable equal to the decibel output

Thanks

Hve a look at this guide from the docs. It explains how to access the different parts of a message.
https://nodered.org/docs/user-guide/messages

That will return the msg object that can contain whatever you want. If objects are new to you taking time to read an online javascript guide on objects and arrays is time well spent as you have already discovered they are fundamental in Node-RED. The w3schools javascript object and arrays guide is often recommended, easily findable with google

Thank you, one more question

I am trying to implement this state machine:

Can you please explain how I can do that?

Thanks

The author of that State Machine is occasionally on here - but i note the project has not been particularly active lately.

I would suggest you would be better off with this one as the author has provided many documented examples and is also quite often on the forums here

Craig