Hello! I am a beginner. I am building a circuit on Tinkercad which is an online website for building I am using an LED and accelerometer in my circuit. The idea is that when a person is lying down the accelerometer will notice that the abs(x)<0.1 and will take recording of that persons body temperature. All recordings will go into an array which will be used to find an average body temperature. Then if the person when in resting state (so abs(x)<0.1) has a higher body temperature, within the range of +0.3C , than usual the LEDs will light up. Otherwise if the person is moving the LEDs should not light up. I think the code keeps on recalculating the average over and over again which it should not. It should only be once and use that average every time when comparing the the body temperature measured at any specific moment when the person is at rest. Not every time it detects resting it recalcualtes the average. What line of code do you recon I should add and where?
//set ovulation temperature range
const int ovulation_a = 90;
const int ovulation_b = 120;
//set array range for temperature
const int MaxTemps = 100;
//set variables
const int x_pin = A0;
const int y_pin = A1;
const int z_pin = A3;
const float sensitivity = 0.8; //given in datasheet
const float Vref = 5.0; //voltage reference
const float Vzerog = 1.8; //voltage at zero G (as given in datasheet)
float x;
float y;
float z;
float avg;
float tempFs [MaxTemps];
int idx = 0;
float persTemp;
//circuit setup
void setup()
{
pinMode(A2, INPUT); //sensor
pinMode(12, INPUT); //red LED
pinMode(2, OUTPUT); //blue LED
pinMode(3, OUTPUT); //green LED
pinMode(4, OUTPUT); //red LED
analogReference(EXTERNAL);
Serial.begin(9600);
}
//circuit behaviour
void loop()
{
if(digitalRead(12)==HIGH)
{
//motion sensor
x = (analogRead(x_pin) - 512) * 3.3 / (sensitivity * 1023);
Serial.print("x: ");
Serial.println(x);
//temperature sensor
int sensor = analogRead(A2);
float voltage = (sensor / 1024.0) * 5.0;
float tempC = (voltage - 0.5) * 100;
float tempF = (tempC * 1.8) + 32;
Serial.print("temp: ");
Serial.print(tempF);
///Recording Reference Temperature
if (MaxTemps > idx){
tempFs [idx++] = tempF;
}
else {
float sum = 0;
for(int loop = 0; loop < 100; loop++) {
sum = sum + tempFs[loop];
}
avg = sum / 100;
persTemp = avg;
}
//only show results if resting
if (persTemp >= ovulation_a && persTemp <= ovulation_b && abs(x) < 0.1)
{ //ovulating
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
Serial.println(" Ovulating");
//wait for 100 miliseconds
}
else
{ //not ovulating
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
Serial.println(" Not Ovulating");
}
}
else {
//Get Reference Temperature
}
delay(1000);
}
You get one temperature sample each second and average the first 100 samples. That means you won't calculate an 'avg' or 'persTemp' for the first 100 seconds and after 100 seconds you will calculate the same average forever.
It appears that that the 100 samples of temperature are being collected even if the accelerometer does not detect a resting state. I suspect that is your issue.
Try this:
//set ovulation temperature range
const int ovulation_a = 90;
const int ovulation_b = 120;
//set array range for temperature
const int MaxTemps = 100;
//set variables
const int x_pin = A0;
const int y_pin = A1;
const int z_pin = A3;
const float sensitivity = 0.8; //given in datasheet
const float Vref = 5.0; //voltage reference
const float Vzerog = 1.8; //voltage at zero G (as given in datasheet)
float x;
float y;
float z;
float avg;
float tempFs [MaxTemps];
int idx = 0;
float persTemp;
//circuit setup
void setup()
{
pinMode(A2, INPUT); //sensor
pinMode(12, INPUT); //red LED
pinMode(2, OUTPUT); //blue LED
pinMode(3, OUTPUT); //green LED
pinMode(4, OUTPUT); //red LED
analogReference(EXTERNAL);
Serial.begin(9600);
}
//circuit behaviour
void loop()
{
if (digitalRead(12) == HIGH)
{
//motion sensor
x = (analogRead(x_pin) - 512) * 3.3 / (sensitivity * 1023);
Serial.print("x: ");
Serial.println(x);
if (abs(x) < 0.1)
{
//
// Resting State
//
//temperature sensor
int sensor = analogRead(A2);
float voltage = (sensor / 1024.0) * 5.0;
float tempC = (voltage - 0.5) * 100;
float tempF = (tempC * 1.8) + 32;
Serial.print("temp: ");
Serial.print(tempF);
///Recording Reference Temperature
if (MaxTemps > idx)
{
tempFs [idx++] = tempF; // record reference temperature sample
if (idx >= MaxTemps)
{
float sum = 0;
for (int loop = 0; loop < 100; loop++) {
sum = sum + tempFs[loop];
}
avg = sum / 100;
persTemp = avg;
}
return; // return since we don't have a reference temperature yet.
}
//only show results if resting
if (persTemp >= ovulation_a && persTemp <= ovulation_b)
{ //ovulating
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
Serial.println(" Ovulating");
//wait for 100 miliseconds
}
else
{ //not ovulating
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
Serial.println(" Not Ovulating");
}
}
}
delay(1000);
}
So I tried the whole exact code you send! The thing is that after it detects resting phase and calculates the average temperature it needs to then compare this average with any new temperature measured. And if the new temperature measure is above +0.3C the LEDs should not light up. If it is within the +0.3C the LEDs should light up. This is only for resting state. If the person is not resting then the LEDs should not light up. Now the problem in the circuit is that after it calculates the average the LEDs light up and do not switch off even if there is no more resting state or if the temperature measure is way more than +0.3C which is what I am trying to achieve.
They are different stages and codes trying to achieve different conclusions. This should be the final question as once I get this done I finish the coding for this part. Thanks for the help! Also for the pin names I do not think it is that big of an issue so I will leave them like that.