dstroy0
Zeroes and Ones
You got a fren!
Yeah! We found him yowling in the bushes out back.
You got a fren!
A buddy of mine is building an arcade cabinet with rotating screen so it can play cames like centipede and defender. He's got the motor on limit switches now but has to use trim to get it level. He's thinking about using an accelerometer. Thought you might have an elegant solution.
A buddy of mine is building an arcade cabinet with rotating screen so it can play cames like centipede and defender. He's got the motor on limit switches now but has to use trim to get it level. He's thinking about using an accelerometer. Thought you might have an elegant solution.
We had that very discussion and didn't know how the accelerometer would handle being mounted at an angle. The math is there to calibrate it, just wasn't sure how. He also looked into it a little since we talked and apparently there are other software hurdles too.just a little more software engineering involved
We had that very discussion and didn't know how the accelerometer would handle being mounted at an angle. The math is there to calibrate it, just wasn't sure how. He also looked into it a little since we talked and apparently there are other software hurdles too.
Thanks.
You would dig it. I'll get some pictures. The cabinet was cut on a his 3D router table. He went through several emulator (pc and raspi based) methods but he found this thing called a flipboard that could handle the flip in aspect ratios without letterboxing.youre welcome, no problem. I’m curious about the project it sounds cool.
hello little guy!
void setup(void)
{
ads1115_0x48.begin(0x48); // Initialize ads1115 at address 0x48 3.3v max input
ads1115_0x48.setGain(GAIN_ONE);
ads1115_0x48.setDataRate(RATE_ADS1115_128SPS);
}
/*
mathematical constants
*/
#define ENUMBER 2.7182818284590452353602874713527 //euler's number
/*
thermistor settings
*/
#define THERMISTORNOMINAL 100000 // resistance at 25 degrees C
#define TEMPERATURENOMINAL 25 // temp. for nominal resistance (almost always 25 C)
#define NUM_SAMPLES 5 // how many samples to take and average
#define BCOEFFICIENT 3950 // The beta coefficient of the thermistor (usually 3000-4000)
/*
0x48 ads1115
series resistor values
measure resistance before installing and record it here
*/
#define AIN0_R 100000
#define AIN1_R 100000
#define AIN2_R 100000
#define AIN3_R 100000
/*
0x48 ads1115
thermistor 1-4 temperature calibration offset in degrees Celsius
*/
#define THERMISTOR_0_TEMP_C_OFFSET 0
#define THERMISTOR_1_TEMP_C_OFFSET 0
#define THERMISTOR_2_TEMP_C_OFFSET 0
#define THERMISTOR_3_TEMP_C_OFFSET 0
void get_thermistor_temperatures()
{
//thermistor voltage divider series resistors
const uint32_t SERIES_RESISTOR_VALUES[4] = {AIN0_R,
AIN1_R,
AIN2_R,
AIN3_R
};
//temperature offset in degrees Celsius
const float offset[4] = {THERMISTOR_0_TEMP_C_OFFSET,
THERMISTOR_1_TEMP_C_OFFSET,
THERMISTOR_2_TEMP_C_OFFSET,
THERMISTOR_3_TEMP_C_OFFSET
};
static uint8_t num_ads_samples = 0; //sample index
static uint16_t samples[4][NUM_SAMPLES] = {0}; //2d sample array
static bool calculate_temp = false; //flag is assigned true when num_ads_samples is assigned 0 (rollover)
float average[4] = {0}; //array to hold sample averages
float steinhart[4] = {0}; //array to hold temperatures
static uint32_t timer = millis(); //sample delay timer
if ((millis() - timer) >= 5UL) //non blocking delay
{
if (num_ads_samples <= NUM_SAMPLES) //only take a sample if the samples[R][C] array C index value is less than the NUM_SAMPLES macro
{
for (uint8_t i = 0; i < (NUM_SAMPLES-1); i++) //count to NUM_SAMPLES - 1
{
samples[i][num_ads_samples] = ads1115_0x48.readADC_SingleEnded(i); //start a single ended conversion, if this is not set to blocking in setup this will block
}
num_ads_samples++; //increment the index
if (num_ads_samples > NUM_SAMPLES) //if the index is greater than the number of samples we are supposed to take (last sample)
{
num_ads_samples = 0; //reset the index from 6 to 0
calculate_temp = true; //we've got enough readings to average that we can calculate the temp
}
}
timer = millis(); //reset the timer
}
if (calculate_temp == true) //if we have the samples
{
for (int i = 0; i < 4; i++) //outer for loop is where the temperature calculation happens
{
for (int j = 0; j < NUM_SAMPLES; j++) //inner for loop
{
average[i] += float(samples[i][j]); //use inner for loop to add up all the samples from one ads1115 channel
}
average[i] /= float(NUM_SAMPLES); //average the samples
// convert the value to resistance
float resistance = ((31500.0 / average[i]) - 1.0);
resistance = float(SERIES_RESISTOR_VALUES[i]) / resistance;
// convert to temperature
// magic number 273.15 is to convert from kelvin to degrees Celsius
steinhart[i] = resistance / float(THERMISTORNOMINAL);
steinhart[i] = log(steinhart[i]);
steinhart[i] /= float(BCOEFFICIENT);
steinhart[i] += 1.0 / (float(TEMPERATURENOMINAL) + 273.15);
steinhart[i] = 1.0 / steinhart[i];
steinhart[i] = steinhart[i] - 273.15;
tx_payload.leaf_temp_c[i] = steinhart[i] + offset[i]; // deg celsius + calibration offset
//c to f (0°C × 9/5) + 32
tx_payload.leaf_temp_f[i] = (tx_payload.leaf_temp_c[i] * (9 / 5)) + 32;
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < NUM_SAMPLES; j++)
{
samples[i][j] = 0; //assign zero to samples[R][C] array elements
}
}
VPDcalc(); //calculate vapor pressure deficit with new leaf temperatures
calculate_temp = false; //we just calculated, time to take more samples
}
}
void VPDcalc()
{
/*
Calculate VPD and convert to kPa
SVP formula, e is euler's number T is temp in celsius
SVP = 610.78 x e^(T / (T + 238.3) x 17.2694))
*/
float SVP[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
float vpd_kpa[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
float rh;
float temp[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
temp[0] = tx_payload.air_temperature_c;
for (uint8_t i = 0; i < 4; i++)
{
temp[i + 1] = tx_payload.leaf_temp_c[i];
}
rh = tx_payload.air_relative_humidity;
for (int i = 0; i < 5; i++)
{
float SVPexp = ((temp[i] / (temp[i] + 238.3)) * 17.2694);
float SVPpow = pow(ENUMBER, SVPexp);
float SVP_t = (610.78 * SVPpow) / 1000.00; //convert to kpa
SVP[i] = SVP_t;
if (i == 0)
{
//VPD = SVP * (1.00 - rh / 100.00)
vpd_kpa[i] = ((1.00 - (rh / 100.00)) * SVP[i]);
}
else
{
//LVPD = LSVP - (SVP * (rh / 100));
vpd_kpa[i] = (SVP[i] - (SVP[0] * rh / 100.00));
}
}
for (int i = 0; i < 5; i++)
{
tx_payload.vpd_kpa[i] = vpd_kpa[i];
}
}
Ahh an orange guy!