Arduino Magnetometer state change - c

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;
}

Related

I am trying to send light sensor data to a microprocessor and getting "call of overloaded 'print(const char[19],unsigned int&)' is ambiguous" error

I have stored light sensor values in comb1, as an array in an unsigned int. I am trying to send these values to a microprocessor. The values are taken from a sensor stored in an array. Then I am trying to send the commands through this:
for(int i = 0; i < 6; i++) {
Serial1.print("AT+SEND=488,3,%u\r\n", comb1[i]);
}
The entire code compiles fine until I add this line of code. I receive this error message:
Energia: 1.8.11E23 (Windows 10), Board: "MSP-EXP430FR2355LP"
C:\Users\turne\OneDrive\Documents\Energia\M_Station\M_Station.ino: In function 'void loop()':
M_Station:137:55: error: call of overloaded 'print(const char [19], unsigned int&)' is ambiguous
C:\Users\turne\OneDrive\Documents\Energia\M_Station\M_Station.ino:137:55: note: candidates are:
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:63:12: note: size_t Print::print(unsigned char, int) <near match>
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:63:12: note: no known conversion for argument 1 from 'const char [19]' to 'unsigned char'
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:64:12: note: size_t Print::print(int, int) <near match>
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:64:12: note: no known conversion for argument 1 from 'const char [19]' to 'int'
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:65:12: note: size_t Print::print(unsigned int, int) <near match>
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:65:12: note: no known conversion for argument 1 from 'const char [19]' to 'unsigned int'
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:66:12: note: size_t Print::print(long int, int) <near match>
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:66:12: note: no known conversion for argument 1 from 'const char [19]' to 'long int'
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:67:12: note: size_t Print::print(long unsigned int, int) <near match>
C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\cores\msp430/Print.h:67:12: note: no known conversion for argument 1 from 'const char [19]' to 'long unsigned int'
Multiple libraries were found for "Wire.h"
Used: C:\Users\turne\OneDrive\Documents\energia-1.8.10E23\hardware\energia\msp430\libraries\Wire
exit status 1
call of overloaded 'print(const char [19], unsigned int&)' is ambiguous
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
This is my whole code:
#include <Wire.h>
#include <msp430.h>
#define VEML7700 0x10
// digital pin 40 has a pushbutton attached to it:
const int Switch = 24;
String DataIn; // Variable to store in the String value
int Sendback = 0;
int Sendreq = 0;
int maintain = 0;
unsigned int comb [6];
unsigned int comb1 [6];
void setup() {
Serial1.begin(115200); // Set up Serial to 115200 baud
pinMode(Switch, OUTPUT);
digitalWrite(Switch, LOW); // turn off switch
// I2C protocol set up
Wire.begin();
Wire.beginTransmission(VEML7700);
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x08);
Wire.endTransmission();
Wire.beginTransmission(VEML7700);
Wire.write(0x01);
Wire.write(0x00);
Wire.write(0x00);
Wire.endTransmission();
Wire.beginTransmission(VEML7700);
Wire.write(0x02);
Wire.write(0xFF);
Wire.write(0xFF);
Wire.endTransmission();
Wire.beginTransmission(VEML7700);
Wire.write(0x03);
Wire.write(0x04);
Wire.write(0x00);
Wire.endTransmission();
}
void loop() {
if (Serial1.available()) { // Serial is receiving?
DataIn = Serial1.readString(); // Reading from Serial
if (DataIn.indexOf("Wake!") > 0) { // Checking for "Wake!" String
}
//storing light sensor values to be sent to 'M' Station
for (int i = 0; i < 3; i++) {
int Cup = Wire.read(); // receive a byte as character
int Cdown = Wire.read(); // receive a byte as character
if (Cdown < 200) {
maintain = 1;
delay(10);
}
else {
maintain = 0;
delay(10);
}
comb[i] = Cdown * 256 + Cup; // array to get assigned values in each position
}
digitalWrite(Switch, HIGH); // turn on switch////////////////////////////////////////////////////////////////////////////
delay(10);
//storing light sensor values to be sent to second set 'M' Station
{
for (int i = 3; i < 6; i++) {
int Cup = Wire.read(); // receive a byte as character
int Cdown = Wire.read(); // receive a byte as character
if (Cdown < 200) {
maintain = 1;
delay(10);
}
else {
maintain = 0;
delay(10);
}
comb[i] = Cdown * 256 + Cup; // array to get assigned values in each position
}
}
for (int i = 0; i < 6; i++) {
//Serial.println(comb[i]);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (Serial1.available()) { // Serial is receiving?
DataIn = Serial1.readString(); // Reading from Serial
//storing light sensor values to be sent to 'M' Station
for (int i = 0; i < 3; i++) {
int Cup = Wire.read(); // receive a byte as character
int Cdown = Wire.read(); // receive a byte as character
if (Cdown < 200) {
maintain = 1;
delay(10);
}
else {
maintain = 0;
delay(10);
}
comb1[i] = Cdown * 256 + Cup; // array to get assigned values in each position
}
digitalWrite(Switch, LOW); // turn off switch/////////////////////////////////////////////////////////////////
delay(10);
//storing light sensor values to be sent to 'M' Station
for (int i = 3; i < 6; i++) {
int Cup = Wire.read(); // receive a byte as character
int Cdown = Wire.read(); // receive a byte as character
if (Cdown < 200) {
maintain = 1;
delay(10);
}
else {
maintain = 0;
delay(10);
}
comb1[i] = Cdown * 256 + Cup; // array to get assigned values in each position
}
Sendback = 2;
Sendreq = 0;
maintain = 0;
for (int i = 0; i < 6; i++) {
Serial1.print("AT+SEND=488,3,%u\r\n", comb1[i]);
}
}
if (Sendback == 1) {
Serial1.print("AT+SEND=488,3,Up!\r\n"); // Send AT command with String "Up!"
delay(10);
Sendback = 0;
Sendreq = 1;
}
if (Sendreq == 1) {
Wire.beginTransmission(VEML7700);
Wire.write(0x04);
Wire.write(0x04);
Wire.endTransmission(false);
Wire.requestFrom(VEML7700, 2, true);
while (Wire.available()); // slave may send less than requested
}
if (maintain == 1) {
Serial1.print("AT+SEND=488,4,req!\r\n"); // Send AT command with String "req!"
delay(10);
maintain = 0;
}
if (Sendback == 2) {
Serial1.print("AT+SEND=488,5,Down!\r\n"); // Send AT command with String "Down!"
delay(10);
Sendback = 0;
Sendreq = 0;
maintain = 0;
}
delay(100);
}
Please let me know if you need any more information. I think overloading means that there are different kinds of information stored on comb1 and the compiler does not know which to choose from? But comb1 is declared as an unsigned int and nothing but integers are in the value. I do not know if I have the wrong understanding of what overloaded means, or if I am assigning multiple kinds of data in comb1. Please let me know what you think.
Serial1.print("AT+SEND=488,3,%u\r\n", comb1[i]);
print doesn't work with formatted strings. You need to use printf.

BLE data inconsistency with HM-10 and Arduino Nano

We have a project that controls a led strip of 80, that is connected via mobile app. The components we used are as follows:
Arduino Nano Board
HM - 10 Bluetooth module
WS2812b Led Strip
On the app, user selects the colors(up to 5), animation (optional), animation speed and brightness. The selected configuration is transmitted to the BLE module with a certain throttle and debouncing. The color(selected on a color wheel on the app) and brightness transmits fine, without any issues.
The problem we encounter, is that when certain animation is active, if the user changes the animation speed via the app, the arduino part locks itself and will not accept any more commands.
To activate a configuration with animation, we send the data from app to arduino as follows:
<l255180200,240135068:089;04200>
The format is: < [mode] [colors(with ',')] : [brightness] ; [animationCode(2 digit)] [animationSpeed] >
At first, we had some inconsistencies with consecutive data, so we implemented the following for data acquisition:
void loop()
{
// Read all serial data available, as fast as possible
while (bleSerial.available() > 0)
{
char inChar = bleSerial.read();
if (inChar == SOP)
{
index = 0;
inData[index] = '\0';
started = true;
ended = false;
}
else if (inChar == EOP)
{
ended = true;
break;
}
else
{
if (index < 79)
{
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
// We are here either because all pending serial
// data has been read OR because an end of
// packet marker arrived. Which is it?
if (started && ended)
{
// The end of packet marker arrived. Process the packet
Serial.println(inData);
Serial.println(inData[0]);
char mode = inData[0];
if (mode == 'p')
{
togglePower(inData);
finalizeRead();
return;
}
if (mode == 'b')
{
changeBrightness(inData);
finalizeRead();
return;
}
if (mode == 't')
{
char *themeNo = strtok(NULL, ";");
int themeCode = valueFromString(themeNo, 0, 2);
theme(themeCode);
}
// if (mode == 'e') {
// sound();
// return;
// }
char *colorsWithBrightness = strtok(inData, ";");
char *animation = strtok(NULL, ";");
char *colors = strtok(colorsWithBrightness, ":");
char *brightness = strtok(NULL, ":");
custom(colors, brightness, animation);
finalizeRead();
}
}
void finalizeRead()
{
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
int valueFromString(char *string, int start, int width)
{
int value = 0;
for (int n = 0; n < width; n++)
value = value * 10 + string[start + n] - '0';
return value;
}
So the custom function is called when the mode == 'l'. And in custom function, we perform as follows:
void custom(char *colors, char *brightness, char *animation)
{
char *trueColors = strtok(colors, "l");
char *colorsSplit = strtok(trueColors, ",");
int colorCount = 0;
uint32_t colorArray[5] = {};
while (colorsSplit != NULL)
{
int r = valueFromString(colorsSplit, 0, 3);
int g = valueFromString(colorsSplit, 3, 3);
int b = valueFromString(colorsSplit, 6, 3);
colorArray[colorCount] = strip.Color(r, g, b);
colorCount++;
colorsSplit = strtok(NULL, ",");
}
int ledsPerSegment = ledCount / colorCount;
for (int n = 0; n < colorCount; n++)
{
int currentSegment = (n + 1) * ledsPerSegment;
Serial.println(currentSegment);
for (int z = n * ledsPerSegment; z < (n + 1) * ledsPerSegment; z++)
{
strip.setPixelColor(z, colorArray[n]);
}
}
strip.setBrightness(atoi(brightness));
strip.show();
Serial.println("Done");
if (animation)
{
int animationCode = valueFromString(animation, 0, 2);
int animationSpeed = valueFromString(animation, 2, 3);
Serial.println(animationSpeed);
if (animationCode == 1)
breath(animationSpeed, atoi(brightness));
else if (animationCode == 7)
pulse(animationSpeed, colorArray, colorCount);
}
}
The problem occurs in pulse animation, which is like this:
void pulse(int wait, uint32_t colorArray[], int colorCount)
{
black();
while (bleSerial.available() <= 0)
{
for (i = 0; i < colorCount && bleSerial.available() <= 0; i++)
{
for (j = 0; j < ledCount / 2 && bleSerial.available() <= 0; j++)
{
strip.setPixelColor(39 - j, colorArray[i]);
strip.setPixelColor(40 + j, colorArray[i]);
strip.show();
delay(wait);
}
black();
}
}
}
We initialize the animation without any issues using the following:
<l255180200,240135068:089;04200>
As soon as we adjust the animation speed from the app, we send about 2 new configurations per second, which is the same as above, only with different speed (last 3 characters before '>'). The arduino part randomly receives the data incorrectly, losing 2-3 characters, which is like <l2551800,240135068:089;04200>
The loss of characters usually occurs on different parts of the string, but always consecutive characters are misread happen each time. Also, sometimes we get a backwards question mark.
We are not sure where we implement wrong, so any help is appreciated on solving this issue.
Thanks!

multiple analog inputs to produce individual averages for each channel

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);
}
}

Saving int value into Eeprom and loading it back into a value again

so i am trying to save an integer value into Eeprom and load it back into a value again. But the problem is, that i can't load the saved int value correctly into the new int value.
I am doing this, because I want to compare the new int value with the already saved one, to control a stepper motor with the rotations got from that value.
void SaveParam(int* param) {
Serial.print("Saving Param: ");
//Serial.println(param);
EEPROM.begin(512);
for (int i = 0; i < 4; i++)
EEPROM.write(i+500, (int)param[i]);
EEPROM.end();
}
int LoadParam(){
int b[10];
EEPROM.begin(512);
for (int i = 0; i < 4; i++)
b[i]= byte(EEPROM.read(i+500));
EEPROM.end();
return b[10];
}
// main part
int b = (int)LoadParam();
int* val = &i;
if (i>b) {
Serial.print("Motor is going down (clockwise) ");
MotorMoveDown(i);
SaveParam(val);
Serial.println(b);
} else if (i<b) {
Serial.print("Motor is going up (counter-clockwise)");
MotorMove(i);
}

Arduino the void loop() function isn't looping

I'm new to Arduino and I wrote the beginning a code that is supposed to play games read stories and more on an LCD display.
Here's my code
#include <LiquidCrystal.h>
// Arduino pins number
const int SW_pin = 2; // digital pin connected to switch output
const int X_pin = 0; // analog pin connected to X output
const int Y_pin = 1; // analog pin connected to Y output
const int LCD_RS = 7;
const int LCD_Enable = 8;
const int LCD_D4 = 9;
const int LCD_D5 = 10;
const int LCD_D6 = 11;
const int LCD_D7 = 12;
LiquidCrystal lcd(LCD_RS, LCD_Enable, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
// Basic vars
int none = 0;
String Apps[2] = {"App selector","Credits"};
int CurrentApp = 0;
int Yaxis = 1;
int Xaxis = 1;
int HiCh = 0;
int button;
int JXaxis;
int JYaxis;
void Credits() { // CREDITS
Serial.print("- Credits app loading \n");
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Credits app");
lcd.setCursor(0,1);
Serial.print("- Credits app loaded \n");
}
void setup() { // SETUP
Serial.begin(9600);
Serial.print("[2J");
Serial.print(" Serial Monitor opened \n \n");
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("App selector");
Serial.print("- App selector menu \n");
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
lcd.setCursor(0,1);
lcd.print(Apps[0]);
}
void SelectApp() { // SELECTAPP
switch (HiCh) {
case (1):
CurrentApp = 1;
Credits();
break;
default:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Error");
Serial.print("- App loading error \n");
}
}
void loop() { // LOOP
while (none == 0) {
button = digitalRead(SW_pin);
int JYaxis = analogRead(Y_pin) / 128;
int JXaxis = analogRead(X_pin) / 128;
if (CurrentApp == 0) {
for (;;) {
if (button == 0) {
SelectApp();
}
if (JYaxis <= 1) {
if (HiCh != 0) {
HiCh = HiCh - 1;
delay(300);
}
}
if (JYaxis >= 7) {
HiCh = HiCh + 1;
delay(300);
}
}
}
}
}
I am only using one joystick as the controller and I have an Arduino UNO R3 board
I know a lot of other people have written about this and a lot of people have fixed the issue too but I cannot find the problem in my code...
I'm sure it's an error during the execution of the script that blocks the rest but I can't find where it is.
Thank you in advance!
If you need any specifications ask them to me and I'll try to answer them.
That code has a couple of issues.
In the loop() function you wouldn't normally make an infinite loop, you just put one run of your loop. That is, remove the while.
On the other hand, using delay() is not a great idea, as the processing loop will stop there and continue after specified time. The behavior you're trying to achieve is better implemented using timer interrupts.

Resources