I'm using an Arduino Uno with an Adafruit Motor Shield (v2) in order to power and control a motor and a LIS3DH accelerometer. With a simpler code in which the motor just goes forward for a certain number of pulses (output by the encoder), the identical function for the accelerometer outputs correct values. The code is shown below.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_Sensor.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#define pi 3.14159
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
float distance = 30;
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
unsigned int pulsesperturn = 56 * 64 / 2 ;
float circumference = 5.25 * 3.14159;
int pulses;
//int count = 0;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void) {
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//
}
void loop() {
// // }
// myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
// myMotor->run(FORWARD);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
// myMotor->run(BACKWARD);
// myMotor->setSpeed(255);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
if (pulsesperturn <= pulses ) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
myMotor->setSpeed(0);
stoppedAccel();
pulses = 0;
}
// Then print out the raw data
// Serial.print("X: "); Serial.print(lis.x);
// Serial.print(" \tY: "); Serial.print(lis.y);
// Serial.print(" \tZ: "); Serial.print(lis.z);
// for (int a = 1; a < 20; a = a + 1) {
// lis.read(); // get X Y and Z data at once
// sensors_event_t event;
// lis.getEvent(&event);
//
// /* Display the results (acceleration is measured in m/s^2) */
// // Serial.print(" \tAngle: "); Serial.print(angle);
// //
// // Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// // Serial.println(" m/s^2 ");
//
// Serial.println();
// //
// // char buffer[5];
// // Serial.print("#S|WRITEDATA|[");
// // Serial.print(angle); // accels
// // Serial.println("]#");
//
// // WriteAccel();
// delay(10);
// }
// myMotor->run(FORWARD);
//
// myMotor->run(RELEASE);
// myMotor->setSpeed(255);
// if (distance / circumference * pulsesperturn <= pulses) {
// myMotor->setSpeed(0);
// delay(2500);
// }
// myMotor->setSpeed(255);
// myMotor->run(FORWARD);
// pulses = 0;
Serial.print("pulses = ");
Serial.println(pulses);
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
/* Or....get a new sensor event, normalized */
}
void counter()
{
pulses++;
}
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(10);
}
}
In this code, which runs the motor forward for a distance 6 times and then runs it backward for the same distance it went forward, the motor runs correctly and the accelerometer says that it has been found but it outputs exclusively null values.
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void)
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
// myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}
void loop() {
motorDirection();
}
void counter()
{
pulses++;
}
void bcounter()
{
b++;
}
void motorDirection()
{
while (b < 6) {
myMotor->run(FORWARD);
readInt();
if (500 * conversion <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
pulses = 0;
bcounter();
if (b == 6) {
stoppedAccel();
}
delay(1500);
}
// break;
}
while (b == 6) {
myMotor->run(BACKWARD);
readInt();
if (500 * b <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
bcounter();
stoppedAccel();
pulses = 0;
delay(500);
break;
}
}
while (b > 6) {
b = 0;
break;
}
}
// 169 forward per 1000, 171 backward
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(100);
}
}
void readInt()
{
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
Serial.print("pulses = ");
Serial.println(pulses);
}
I have tried various things but I have little background in CS, especially in C++, so my attempts haven't been fruitful. Any advice would be helpful.