multiple analog inputs to produce individual averages for each channel - arrays

I am trying to put four analog inputs into individual channels that contain an array. Once that happens I am trying to get an average of each channel's array getting a single int or float. Lastly, I want to compare the averages in an if statement to get a serial print and divide the compared averages.
I am just confused on what in the code I pieced together is necessary.
Thank you for any advice or help.
Here is my code below
#include <Servo.h>
float sVal0 = 0.0;
float sVal1 = 0.0;
float sVal2 = 0.0;
float sVal3 = 0.0;
float sVal02 = 0.0;
float sVal13 = 0.0;
const int numReadings = 10; //# of readings needed to average
const int numChannels = 4; // 4 analog outputs
int readings[numChannels][numReadings]; // the readings from the analog input
int index; // the index of the current reading
void setup () {
Serial.begin(9600);
}
void loop () {
sVal0 = analogRead(A0);
sVal1 = analogRead(A1);
sVal2 = analogRead(A2);
sVal3 = analogRead(A3);
for (int chan = 0; chan <= numChannels; ++chan ){
Serial.println(sVal0[chan]); // serial print each array
Serial.println(sVal1[chan]);
Serial.println(sVal2[chan]);
Serial.println(sVal3[chan]);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
index = index + 1;
}
if (index >= numReadings) {
index = 0;
sVal0_avg = sVal0[chan]/numReadings; // get average
sVal1_avg = sVal0[chan]/numReadings;
sVal2_avg = sVal0[chan]/numReadings;
sVal3_avg = sVal0[chan]/numReadings;
}
}
if (sVal1_avg > sVal3_avg) {
Serial.print("1 avg: );
Serial.println(sVal1_avg);
sVal31 = sVal3_avg / sVal1_avg;
Serial.print("comparison : ");
Serial.println(sVal31);
}
}

Related

Creating a histogram from a large file

I have two large files containing float-type data. I want to create a histogram using the two files. However, to access the 256^3 data values, I tried using a nested for-loop in C which failed with a segmentation fault.
Is there an alternative method that I can use to access the data values that would not result in a segmentation fault?
Here is my code:
int main () {
int i,j,k,n_grid;
float pc,mass_g,spat_res,vol_pix,max_vel,min_vel;
float velocity,density,max;
long start,index,index1,index2,counter,lSize,dim;
FILE *p,*q;
pc = 3.085677e-18; //1 parsec in cm
n_grid = 256; //dimension of observed portion of input grid
mass_g = 0.0;
spat_res = pc*0.71/512; //spatial resolution of grid in cm
vol_pix = pow(spat_res,3); //volume of each voxel in cm^3
p = fopen("../dens_104/rho_052.dat","rb");
q = fopen("../dens_104/velz.dat","rb");
if (!p){
printf("Unable to open dens file!");
return 0;
}
else if (!q){
printf("Unable to open the velx file!");
return 0;
}
//obtain file size(s)
fseek(p,0,SEEK_END);
lSize = ftell(p);
rewind(p);
dim = pow(lSize/sizeof(float),1.0/3.0); //actual size of input grid
max = 0;
counter = 0;
index = 0;
while(fread(&density,sizeof(float),1,p),!feof(p) && !ferror(p)) {
if(density > max) max = density,index = counter;
counter += 1;
}
start = index - (pow(dim,2)+dim+1)*(n_grid/2-1);
printf("Starting pixel value: %lu, Dimension of cube: %d\n",start,
(int)dim);
printf("The maximum density is: %e with index: %lu \n", max,index);
rewind(p);
fseek(p,start*sizeof(float),SEEK_SET);
fseek(q,start*sizeof(float),SEEK_SET);
max_vel = 0.0;
min_vel = 0.0;
index1 = 0;
index2 = 0;
while(fread(&velocity,sizeof(float),1,q),!feof(q) && !ferror(q)) {
if(velocity > max_vel) max_vel = velocity,index1=counter;
if(velocity < min_vel) min_vel = velocity,index2=counter;
counter += 1;
}
printf("The maximum velocity is: %e with index: %lu\n", max_vel,index1);
printf("The minimum velocity is: %e with index: %lu\n", min_vel,index2);
density = 0.;
for (k=0;k<n_grid;k++){
fseek(p,(start+k*dim*dim)*sizeof(float),SEEK_SET);
for (j=0;j<n_grid;j++){
fseek(p,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
for (i=0;i<n_grid;i++){
fread(&density,sizeof(float),1,p);
mass_g += density*vol_pix;
}
}
}
printf("The mass of the observed cube is: %e \n", mass_g);
}

Fast way to compare frequent input data and storing MAX and MIN values

Let's say I have input data every millisecond.
After 5 seconds I want to output the MAX and MIN Value of the last 5 second time window.
What will be here the fastest way to compare frequent integer input data? I put a very simple example. Is it bad to use something like this in general? Is there a faster way but without using array for buffering?
myMainFuntion() {
int static currentMIN = 30000; // Just initialize to a value that will never be output by getSensorData
int static currentMAX = 0;
int static acquisition_counter = 0;
a = getSensorData() // called each 1 ms
if (a > currentMAX) {
currentMAX = a;
}
if (a < currentMIN) {
currentMIN = a;
}
acquisition_counter++;
if (acquisition_counter == 5000) {
output(MAX);
output(MIN);
}
}
It seems OK, there is not much to be optimized in your function, except for a few details:
the return type should be void instead of omitted.
a is not defined.
you should output currentMIN and currentMAX instead of MIN and MAX.
you should reset the values of the min and max variables after the output.
it is more idiomatic to ut the static keyword in front of the type.
Here is the modified code:
void myMainFuntion(void) {
static int currentMIN = 30000; // Just initialize to a value that will never be output by getSensorData
static int currentMAX = 0;
static int acquisition_counter = 0;
int a;
a = getSensorData() // called every 1 ms
if (a > currentMAX) {
currentMAX = a;
}
if (a < currentMIN) {
currentMIN = a;
}
acquisition_counter++;
if (acquisition_counter == 5000) {
output(currentMAX);
output(currentMIN);
currentMAX = 0;
currentMIN = 30000;
acquisition_counter = 0;
}
}

Finding the largest difference between multiple sets of numbers

I've attempted to create a program which processes a list of outcomes for football games while also processing the results.
The way my program works is you input the number of matches that have been played then you list the results of each match.
Each row in the list has the form of HOME_TEAM_ID | AWAY_TEAM_ID | HOME_TEAM_GOALS | AWAY_TEAM_GOALS
So for example if the user entered (the first line is the number of matches):
2
0 1 5 0
2 3 0 5
My program will then output a row containing: team id, win ratio, win ratio on home games, average point difference in won games ( -1 in case of no home games.) The largest (in terms of point difference) win in a single game and then the ID of that opponent.
0 1.000 1.000 5.000
1 0.000 -1 -1
2 0.000 0.000 -1
3 1.000 -1 5.000
I've completed most of my program but I'm having difficulty implementing one last part. I want to find out the the largest (in terms of goal difference) win in a single game for each team and then the ID of the opponent which they had their largest win in terms of goal difference. (If there aren't any wins then it should simply output -1.)
My first thought was to just loop through the array, setting a variable to the largest win. For each element, check if its point difference is higher than the variable. If it is, replace the variable with the current element's difference.
However I'm getting a compiler error.
1079.c: In function 'main':
1079.c:153:11: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
maximum = resultTable[0];
^
1079.c:157:24: warning: comparison between pointer and integer
if (resultTable[n] > maximum)
^
1079.c:159:17: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
maximum = resultTable[n];
Any help about how to find the largest average point difference, over multiple games, against one particular opponent, would be greatly appreciated.
Here's my full code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//My local variables
int n;
int i;
int input = 0;
int TEAM_ID = 0, NUM_OF_GAMES = 1, WINS = 3, HOME_GAMES = 2, HOME_WINS = 4, HOME_WIN_RATIO = 6, WIN_RATIO = 5, GD = 7;
int homeTeamID, awayTeamID, homeGoals, awayGoals;
static const int NUM_COLUMNS = 10;
static const int NUM_TEAMS = 30;
double resultTable[30][10];
int BEST_WIN_DIFF = 8, BEST_WIN_OPPONENT = 9;
void takeInput();
void sortData();
void printer();
//This method takes the input from the user for homeTeamID, awayTeamID,homeGoals and awayGoals
void takeInput()
{
scanf("%d", &input);
for (n = 0; n < input; n++) {
scanf("%d %d %d %d", &homeTeamID, &awayTeamID, &homeGoals, &awayGoals);
//calls the sortData function
sortData();
}
}
//The table fnction which uses the resultTable variable to put the infomation in a table
void sortData()
{
int goalDiff = homeGoals - awayGoals;
//This will increment the home games,home game counter and the away game
resultTable[homeTeamID][NUM_OF_GAMES]++;
resultTable[homeTeamID][HOME_GAMES]++;
resultTable[awayTeamID][NUM_OF_GAMES]++;
//If the awaygoals is larger than the homegoals then it will set the winner in the results table
if (homeGoals < awayGoals) {
resultTable[awayTeamID][WINS]++; //increment away wins
}
//If the homegoals is larger than the awaygoals then it will set the winner in the results table
else if (homeGoals > awayGoals) {
resultTable[homeTeamID][WINS]++;
resultTable[homeTeamID][HOME_WINS]++; //increment home wins
}
//The goal difference for home and away
resultTable[homeTeamID][GD] = resultTable[homeTeamID][GD] + (homeGoals - awayGoals);
resultTable[awayTeamID][GD] = resultTable[awayTeamID][GD] + (awayGoals - homeGoals);
if (goalDiff > resultTable[homeTeamID][BEST_WIN_DIFF]) {
resultTable[homeTeamID][BEST_WIN_DIFF] = goalDiff;
resultTable[homeTeamID][BEST_WIN_OPPONENT] = awayTeamID;
}
if (-goalDiff > resultTable[awayTeamID][BEST_WIN_DIFF]) {
resultTable[awayTeamID][BEST_WIN_DIFF] = -goalDiff;
resultTable[awayTeamID][BEST_WIN_OPPONENT] = homeTeamID;
}
}
//Calculates the win ratio
void winRatio()
{
for (n = 0; n < 30; n++) {
//This if determines the home win ratio
if (resultTable[n][HOME_GAMES] > 0) {
resultTable[n][HOME_WIN_RATIO] = resultTable[n][HOME_WINS]
/ resultTable[n][HOME_GAMES];
}
if (resultTable[n][NUM_OF_GAMES] > 0) {
resultTable[n][GD] = resultTable[n][GD] / resultTable[n][NUM_OF_GAMES];
}
//This if determines the win ratio
if (resultTable[n][NUM_OF_GAMES] > 0) {
resultTable[n][WIN_RATIO] = resultTable[n][WINS]
/ resultTable[n][NUM_OF_GAMES];
}
}
}
//This method prints out the results
void printer()
{
for (n = 0; n < NUM_TEAMS; n++) {
if (resultTable[n][NUM_OF_GAMES] != 0) {
if (resultTable[n][HOME_WIN_RATIO] == -1) {
printf("%d %.3f %.0f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
else {
printf("%d %.3f %.3f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
}
}
}
//My main function which will be used to call everyother function
int main(void)
{
for (n = 0; n < NUM_TEAMS; n++) {
for (i = 1; i < NUM_COLUMNS; i++) {
resultTable[n][i] = 0;
}
resultTable[n][TEAM_ID] = n;
resultTable[n][HOME_WIN_RATIO] = -1;
resultTable[n][BEST_WIN_DIFF] = -HUGE_VAL;
}
int maximum, location = 1;
for (n = 0; n < 30; n++)
scanf("%d", &resultTable[n]);
maximum = resultTable[0];
for (n = 0; n < 30; n++)
{
if (resultTable[n] > maximum)
{
maximum = resultTable[n];
location = n+1;
}
}
printf("Maximum element is present at location %d and it's value is %d.\n", location, maximum);
return 0;
takeInput();
winRatio();
printer();
return EXIT_SUCCESS;
}
You can't get the information you want (the largest etcetera) from the data you enter into the array because you throw away information you need later to calculate this.
You need to store the input data unchanged into the array, then you can calculate anything from it you want.
In particular, with
//The goal difference for home and away
resultTable[homeTeamID][GD] = resultTable[homeTeamID][GD] + (homeGoals - awayGoals);
resultTable[awayTeamID][GD] = resultTable[awayTeamID][GD] + (awayGoals - homeGoals);
you remember the difference, but that is not enough to calculate the largest win in a single game for each team. Instead, store both homeGoals and awayGoalsand then later calculate the information you want.
Include math.h for HUGE_VAL.
#include <math.h>
Add two extra columns.
static const int NUM_COLUMNS = 10;
static const int NUM_TEAMS = 30;
double resultTable[NUM_TEAMS][NUM_COLUMNS];
int BEST_WIN_DIFF = 8, BEST_WIN_OPPONENT = 9;
Add them to the table function.
void table()
{
int i;
for (n = 0; n < NUM_TEAMS; n++) {
for (i = 1; i < NUM_COLUMNS; i++) {
resultTable[n][i] = 0;
}
resultTable[n][TEAM_ID] = n;
resultTable[n][HOME_WIN_RATIO] = -1;
resultTable[n][BEST_WIN_DIFF] = -HUGE_VAL;
}
}
Add the new code to the end of sortData.
void sortData()
{
...
int goalDiff = homeGoals - awayGoals;
if (goalDiff > resultTable[homeTeamID][BEST_WIN_DIFF]) {
resultTable[homeTeamID][BEST_WIN_DIFF] = goalDiff;
resultTable[homeTeamID][BEST_WIN_OPPONENT] = awayTeamID;
}
if (-goalDiff > resultTable[awayTeamID][BEST_WIN_DIFF]) {
resultTable[awayTeamID][BEST_WIN_DIFF] = -goalDiff;
resultTable[awayTeamID][BEST_WIN_OPPONENT] = homeTeamID;
}
}
and finally update printer to include the extra columns.
void printer()
{
for (n = 0; n < NUM_TEAMS; n++) {
if (resultTable[n][NUM_OF_GAMES] != 0) {
if (resultTable[n][HOME_WIN_RATIO] == -1) {
printf("%d %.3f %.0f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
else {
printf("%d %.3f %.3f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
}
}
}
double resultTable[30][10];
resultTable[x] is a pointer to double [10]
resultTable[x] is a pointer of double *
resultTable[x][y] is double
That is the reason you get the warning
You have more problems in your code
you scanf integers, but pass pointer to double etc etc.

Arduino Magnetometer state change

I currently have a Arduino connected with magnetometer. When metal is detected it shows a 1 but when there is no metal it is a 0. I currently want a count to detect when there is a change in state but ONLY when it goes from a 0 to 1 not a 11 or 10. I have a last state variable set up to capture the previous state and on the next loop back it compares with the current state. Then from there it will send a "2" to my raspberry pi which I have connected. But for some reason the state detect doesn't work. The last State keeps changing with the current state. Can anyone help check out my code.
/* Intialize Variables */
byte data[32]= {0}; //Data buffer for testing data transfer speeds
int k=0;
float headingdegrees;
boolean VehicleDetected;
float high;
float low;
float Average;
float Sum = 0;
unsigned int Counter = 0; //number of attempted transmissions
unsigned int fail_counter = 0; //number of failed transmissions
unsigned int success_counter = 0; //number of successful transmissions
unsigned long rxTimer; //Counter and timer for keeping track transfer info
unsigned long startTime, stopTime;
bool TX=1,RX=0,role=0;
bool car_detected = 0;
int inPin_on = 4; // pushbutton connected to digital pin 4
int inPin_off = 5;
int val = 0; // variable to store the
int fsrPin = 0; // the FSR and 10K pulldown are connected to a0
int fsrReading; // the analog reading from the FSR resistor divider
int fsrVoltage; // the analog reading converted to voltage
unsigned long fsrResistance; // The voltage converted to resistance, can be very big so make "long"
unsigned long fsrConductance;
long fsrForce; // Finally, the resistance converted to force
unsigned int percentage_Transmission = 100;
const unsigned int reset_counter = 5; //number of transmissions before reset
unsigned int arr_transmission_percentage[reset_counter] = {0};
unsigned int arr_index = 0; //To be used for indexing through percentage array
unsigned int i = 0;
unsigned int temp = 0;
float TxRxAve = 100; //Average Transmission percentage
uint32_t displayTimer = 0;
int changeDetected = 0;
int lastState = 0;
int sendChange = 2;
if ( headingdegrees > high ){
VehicleDetected = 1;
}
else if(headingdegrees < low){
VehicleDetected =1;
}
else{
VehicleDetected = 0;
}
//Detect the state change
delay(100);
if(lastState == 0 && VehicleDetected == 1){
changeDetected = 1;
}
else{
changeDetected = 0;
}
//store the current state
// lastState = VehicleDetected;
/***** Sending Data****/
mesh.update();
// Send to the master node every 5 second
if (millis() - displayTimer >= 5000) {
displayTimer = millis();
//if changeDetected = 1 then send a 2 to the raspberry pi
// Send an 'M' type message containing the current millis()
if (changeDetected == 1){
if (!mesh.write(&sendChange, 'M', sizeof(sendChange))) {
// If a write fails, check connectivity to the mesh network
if ( ! mesh.checkConnection() ) {
//refresh the network address
Serial.println("Renewing Address");
mesh.renewAddress();
} else {
Serial.println("Send fail, Test OK");
}
} else {
Serial.print("Begin \n");
Serial.print("Average:"); Serial.println(Average);
Serial.print("Heading (degrees): "); Serial.println(headingdegrees);
Serial.print("Sending Count: "); Serial.println(sendChange);
Serial.print("Last State: "); Serial.println(lastState);
Serial.print("Change: "); Serial.println(changeDetected);
//Serial.print("Data: ");
//Serial.println(data[0]);
Serial.print("Send OK: "); Serial.println(displayTimer);
Serial.print("End \n\n\n");
;
}
}
//if changeDetected = 0 then simplay send the vehicledDetected
else{
if (!mesh.write(&VehicleDetected, 'M', sizeof(VehicleDetected))) {
// If a write fails, check connectivity to the mesh network
if ( ! mesh.checkConnection() ) {
//refresh the network address
Serial.println("Renewing Address");
mesh.renewAddress();
} else {
Serial.println("Send fail, Test OK");
}
} else {
Serial.print("Begin \n");
Serial.print("Average:"); Serial.println(Average);
Serial.print("Heading (degrees): "); Serial.println(headingdegrees);
Serial.print("Vehicle Detected:"); Serial.println(VehicleDetected);
Serial.print("Last State: "); Serial.println(lastState);
Serial.print("Change: "); Serial.println(changeDetected);
//Serial.print("Data: ");
//Serial.println(data[0]);
Serial.print("Send OK: "); Serial.println(displayTimer);
Serial.print("End \n\n\n");
;
}
}
}
while (network.available()) {
RF24NetworkHeader header;
payload_t payload;
network.read(header, &payload, sizeof(payload));
Serial.print("Received packet #");
Serial.print(payload.counter);
Serial.print(" at ");
Serial.println(payload.ms);
delay(500);
}
lastState = VehicleDetected;
}

Moving average algorithm issue

I want to smooth values in realtime. For a reason this code seems to make the microcontroller(arduino - atmel) crash or not respond at least.
This is my code
float tilttemp[] = { 1,1,1,1,1,1,1,1 };
float rolltemp[] = { 1,1,1,1,1 };
float pantemp[] = { 1,1,1,1,1 };
float tiltausgabe = 0;
float rollausgabe = 0;
float panausgabe = 0;
void trackerOutput()
{
for(int i=0; i < sizeof(tilttemp) - 1; i++)
{
tilttemp[i] = tilttemp[i+1];
}
tilttemp[sizeof(tilttemp)] = tiltAngleLP; //tiltAngleLP is a value that is available
tiltausgabe = 0;
for(int i=0; i < sizeof(tilttemp); i++)
{
tiltausgabe += tilttemp[i];
}
tiltausgabe = tiltausgabe/(sizeof(tilttemp));
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
}
If I leave everything but
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
out I get the output, so something is wrong in the first part.
You don't want sizeof. You want countof.
If you want to know what that is, it is:
#define countof(a) (sizeof(a)/sizeof((a)[0]))
and
array[ countof(array) ] = ...
will not set the last element of array.
It will set the element beyond the last element.

Resources