Analog input wrong values

I have developed a project with Arduino Uno r3 dip version that has lot of sensors and also controls two 12v motors with L298N. everything was working fine when tested with individual program. But i got improper analog readings from joystick when every sensors and their program were put together. due to wrong analog reading the l298n does not enable the motors. I tried to troubleshoot it by separating the motor controlling program from other sensor programs and uploaded it to Arduino . It worked Fine . But every program put together l298n doesn’t work . every other sensors work fine.
Please some one help me debug.
Thanks in advance…
sensors used :

ADXL335 ,pulse Sensor , Ultrasonic sensor, oled 128x32 display, gsm sim900a , L298N, DHT11 sensor, joystick.

#include <DHT.h>
#include <SoftwareSerial.h> //GSM
#include <Wire.h> //OLED
#include <Adafruit_SSD1306.h> //OLED
#define USE_ARDUINO_INTERRUPTS true
#include <PulseSensorPlayground.h>

 //GSM

SoftwareSerial SIM900A(4,3); //GSM PIN 4 & 3
  
 //OLED
 
#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 32 
#define OLED_RESET -1 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

 //DHT11

#define DHTPIN 13 //DHT11 PIN 13
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE); 

 //ADXL 
 
#define ADC_ref 5              
#define zero_x 1.799
#define zero_y 1.799
#define zero_z 1.799
#define sensitivity_x 0.4
#define sensitivity_y 0.4
#define sensitivity_z 0.4
unsigned int value_x;
unsigned int value_y;
unsigned int value_z;
float xv;
float yv;
float zv;
float angle;

 //MOTOR L298N
 
#define enA 9
#define in1 5
#define in2 6
#define enB 10
#define in3 7
#define in4 8
int motorSpeedA = 0;
int motorSpeedB = 0;

 //PULSE SENSOR

PulseSensorPlayground pulseSensor;
const int PulseWire = A3; // PulseSensor ANALOG PIN 3
const int Threshold = 550;           
int myBPM = 0;  
char error="";                               
  
 //ULTRASONIC SENSOR

const int trigPin = 12; //TRIG PIN 12
const int echoPin = 11; //ECHO PIN 11
long duration;
int distance;
int safetyDistance;

 //BUZZER 
 
const int buzz = 1; //BUZZER PIN 1
const int alertLED = 0; //RED LED 0

 //SNOOZE 
  
const int buttonPin = 2; //SNOOZE BUTTON pin 2

unsigned long startMillis;  //TIME MILLIS
unsigned long currentMillis;
const unsigned long period = 10000;
bool snooze = false;

 //SMS SENDING
 
int smsperiod = 40; //TIME 40 SEC
int smsMillis = 0;  //INCREAMENT TIME

void setup() {
 Serial.begin(9600);
//BEGIN OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextColor(WHITE);
//BEGIN GSM
  SIM900A.begin(9600);
//BEGIN DHT
  dht.begin();
//ADXL
  analogReference(ADC_ref);
  
//ULTRASONIC SENSOR PIN MODE
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 
//BUZZER, LED & SNOOZE PIN MODE
  pinMode(buzz, OUTPUT);    
  pinMode(alertLED, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);  
//L298N PIN MODE
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
//PULSE SENSOR CONFIG
  pulseSensor.analogInput(PulseWire);   
  pulseSensor.setThreshold(Threshold); 
  if(!pulseSensor.begin()){
    
  }
    
//WELCOME MESSAGE
  display.clearDisplay();
  display.setCursor(40,5);
  display.setTextSize(3);
  display.println("SWC");
  delay(3000);
  display.display();
  display.clearDisplay();
  display.setCursor(20,5);
  display.setTextSize(2);
  display.println("WELCOME!!");
  delay(2000);
  display.display();
  
}

void loop() { 

//CALL JOYSTICK
  motorControll();

//CALL ULTRASONIC & ADXL
  readDistandAngle();
  delay(700);

//CALL DHT AND PULSE DISPLAY
  readDhtPulse();
  delay(20);
  

}

void readDhtPulse(){
  //READ DHT VALUES
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
//READ PULSE VALUE
  int mypulse = pulseSensor.getBeatsPerMinute();
  if(mypulse>205 && mypulse<550){
    myBPM = 98;
  }
  else if(mypulse>155 && mypulse<550){
    myBPM = 94;
  }
  else if(mypulse>103 && mypulse<550){
    myBPM = 86;
  }
  else if(mypulse>80&&mypulse<103){
    myBPM = mypulse;
  }
  else {
    myBPM = 83;
  }

//OLED DISPLAY TEMP, HUMID & PULSE
      display.clearDisplay();
// display temperature
      display.setTextSize(1);
      display.setCursor(0,4);
      display.print("T: ");
      display.setTextSize(2);
      display.setCursor(17,0);
      display.print(t);
      display.setTextSize(1);
      display.setCursor(77, 6);
      display.print(" C");
// display humidity
      display.setTextSize(1);
      display.setCursor(0, 19);
      display.print("H: ");
      display.setTextSize(2);
      display.setCursor(17, 16);
      display.print(h);
      display.setTextSize(1);
      display.setCursor(77, 21);
      display.print(" %"); 
// display pulse
      display.setTextSize(1);
      display.setCursor(95, 2);
      display.print("Pulse");
      display.setCursor(95, 13);
        if (pulseSensor.sawStartOfBeat()) {     
          display.print(myBPM);
        }
      
      else {
        display.print(myBPM);
      }
      display.setCursor(95, 24);
      display.print("BPM");
      display.display();
}

void motorControll() {
  int xAxis = analogRead(A4); // Read Joysticks X-axis
  int yAxis = analogRead(A5); // Read Joysticks Y-axis
  // x-axis used for forward and backward control
  if (xAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Set Motor B backward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Convert the declining x-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(xAxis, 470, 0, 0, 255);
    motorSpeedB = map(xAxis, 470, 0, 0, 255);
  }
  else if (xAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B forward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(xAxis, 550, 1023, 0, 255);
    motorSpeedB = map(xAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  // y-axis used for left and right control
  if (yAxis < 470) {
    // Convert the declining y-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(yAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
  }
  if (yAxis > 550) {
    // Convert the increasing y-axis readings from 550 to 1023 into 0 to 255 value
    int yMapped = map(yAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA + yMapped;
    motorSpeedB = motorSpeedB - yMapped;
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  // Confine the range from 0 to 255
  if (motorSpeedA < 0) {
    motorSpeedA = 0;
  }
  if (motorSpeedB > 255) {
    motorSpeedB = 255;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B

}

void readDistandAngle() {
  currentMillis = millis(); 

//CHECK FOR SNOOZE
  if (currentMillis - startMillis >= period) {
    snooze=false;
  }

//CHECK FOR ALERT
  if(checkAngle()||checkDist()){ //CALL ANGLE & DIST FUNCTION
    checkForSnooze(); //CALL SNOOZE FUNCTION
    if(snooze==false){
      digitalWrite(alertLED, HIGH);
      digitalWrite(buzz, HIGH);
    }
  }
  else{
    digitalWrite(buzz, LOW);
    digitalWrite(alertLED, LOW);
  }

}

  //ANGLE FUNCTION
bool checkAngle(){
//CALCULATE ANGLE
  value_x = analogRead(A0);
  value_y = analogRead(A1);
  value_z = analogRead(A2);
  xv=(value_x/1024.0*ADC_ref-zero_x)/sensitivity_x;
  yv=(value_y/1024.0*ADC_ref-zero_y)/sensitivity_y;
  zv=(value_z/1024.0*ADC_ref-zero_z)/sensitivity_z;
  angle =atan2(-yv,-zv)*57.2957795+180;
  Serial.print("angle : ");
  Serial.println(angle);
//CHECK ANGLE
  if (angle >=220 || angle<= 168){
    if(snooze==false){
//CHECK ALERT TIME FOR SMS
      checkForAlertSms();
    }
    return true;
  }
  else {
    smsMillis = 0;
    return false;
  }

  
  
}

  //SMS FUNCTION
void checkForAlertSms(){
  if (smsMillis++ > smsperiod ){
      SIM900A.println("AT+CMGF=1");
      delay(1000);
      SIM900A.println("AT+CMGS=\"+918946014837\"\r");
      delay(1000);
      SIM900A.println("Accident ALERT!! Please Check on SWC USER Location : https://www.google.com/maps/place/9%C2%B042'28.9%22N+78%C2%B005'42.5%22E");
      delay(1000);
      SIM900A.println((char)26);
      delay(1000);
      smsMillis = 0;
    }
}

  //DISTANCE FUNCTION
bool checkDist(){
//CALCULATE DISTANCE
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance= (duration/2) * 0.0343;
  safetyDistance = distance;
//CHECK DISTANCE
  if (safetyDistance <= 30){   
    return true;
  }
  else {
    return false;
  }
}

  //SNOOZE FUNCTION
void checkForSnooze(){
  if (digitalRead(buttonPin) == LOW ) { 
    digitalWrite(buzz, LOW);
    digitalWrite(alertLED, LOW);
    snooze = true;
    startMillis = millis();
  }
}

test_swc.ino (9.0 KB)

What exactly does “improper analog readings” mean? What values do you expect and what values are you seeing?

How is everything powered? A schematic with details of ALL power supplies and connections would be useful. It sounds like something may be messing with the analog reference and so confusing the values being read.

Steve

I think a circuit diagram will help here.
I would suspect that a power supply is not up to the task.

5 is not a valid analog reference ID. It CERTAINLY does not mean 5 Volts. I hope you are lucky and it ignores your nonsense :slight_smile: and uses DEFAULT (Vcc. 5V on a 5V system).

Use the named constants defined in the analogReference() documentation.

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  #define DEFAULT 0
  #define EXTERNAL 1
  #define INTERNAL1V1 2
  #define INTERNAL INTERNAL1V1
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  #define DEFAULT 0
  #define EXTERNAL 4
  #define INTERNAL1V1 8
  #define INTERNAL INTERNAL1V1
  #define INTERNAL2V56 9
  #define INTERNAL2V56_EXTCAP 13
#else  
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
#endif

i double checked every sensors voltage inputs with a multimeter. Every sensor was supplied with their required voltage.

I couldn’t understand. what should i put instead of 5 over there for adxl335 to work correct and not interfere with other analog inputs.

I think you are probably seeing noise on the analog input, or there is noise on the power lines, when it’s all powered up.

Consider putting an RC filter at the analog input pin. Separate, and if necessary shield, the analog input wiring from everything else.

ok I will try that but I think its something on the program that makes give wrong output, because I tried removing every sensor from the board and kept just the joystick and L298N then uploaded to Arduino the same program that i uploaded in this forum. It didn’t work. the reading was not correct and it did not enable the motors.

The outputs of the ADXL335 are ratiometric. You should set analogReference(EXTERNAL); and connect the Aref pin to the same voltage as you are supplying to the ADXL355 (1.8 to 3.6V).

Note down the maximum and minimum readings you get when the axis is pointing straight up and straight down. Half-way between them is 0g. The difference between 0g and the maximum is 1g. For each reading, subtract the 0g value and divide by the 1g value to get acceleration on that axis in units of ‘g’.


this is the exact connect i am using

A few things jumped out by just looking at the Fritzing art.

The I2C SCL/SDA pins of an Uno are directly connected to A4/A5.
You can use one pair, or the other, not both.

A SIM900A board draws about 2Amp when transmitting, and can’t be powered from the 5volt pin of the Uno.

Can’t connect anything to pin 0, 1 without upsetting program upload capability.
Leo…

I know its a mess, I just want a solution.

I need to use 4 components that uses analog pins oled, joystick, pulse sensor & adxl335.Theres no way that I can avoid some pins .

should i use a mega board or a separate board Uno or Nano by dividing my projects into two to make things work.

I know about the pins 0, 1 used for serial communication. I read in many articles and other forums that its safe to use 0 and 1 pins when there is no Serial.prinln(); Serial.begin(); and removing the pins while uploading sketch to computer.

For sim900a I will use a separate power supply. thanks for info.

If you need 6 analog inputs AND Wire/TWI/I2C (A4/A5 on the UNO) then the MEGA would be a good choice. It would give you lots of room to grow.

The Leonardo has a few more analog inputs but they share pins with some of the digital pins so you might not have enough digital pins.

You might be able to use a (classic) Nano, which has two more analogue inputs than the Uno.
3.3volt supply is weaker though, so it depends on which oled display you have.

Using pin 0,1 is rarely a good idea, even if you don’t use Serial.begin.
Leo…