void loop() not looping???help please

i am very new to coding and am struggling with the loop not looping, this code is supposed to display on lcd how many degrees i want to tilt a beam and the up/down buttons on sainsmart lcd change the degrees and update it on lcd. from there when the select button is pressed the stepper motor would move accordingly. btw the sensor is a 3-axis accelerometer.

The problem i am having is that nothing is being displayed on the screen, can anyone help?
i attached code below(some was sourced from the internet)

#include <Wire.h> // Must include Wire library for I2C
#include <SFE_MMA8452Q.h> // Includes the SFE_MMA8452Q library
#include <i2c.h>
#include <LiquidCrystal.h>

#define DIR_PIN 2
#define STEP_PIN 3
#define btnUP     1
#define btnDOWN   2
#define btnSELECT 4
#define MMA8452_ADDRESS 0x1D  // 0x1D if SA0 is high, 0x1C if low

//Define a few of the registers that we will be accessing on the MMA8452
#define OUT_X_MSB 0x01
#define XYZ_DATA_CFG  0x0E
#define WHO_AM_I   0x0D
#define CTRL_REG1  0x2A

#define GSCALE 2 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
//1000
// Set the output data rate below. Value should be between 0 and 7
const byte dataRate = 0; // 0=800Hz, 1=400, 2=200, 3=100, 4=50, 5=12.5, 6=6.25, 7=1.56
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;

boolean state = false;
boolean prev_state = false;

int prev_num, num;
int jcnt = 0;
int max_val = 30, min_val = 13;

long time;
long prev_time;
int accel_angle_x, accel_angle_y;

void setup()
{
  pinMode(DIR_PIN, OUTPUT); 
  pinMode(STEP_PIN, OUTPUT);      
  Serial.begin(9600);
  lcd.begin(16, 2); // start the library
  Wire.begin(); //Join the bus as a master
  initMMA8452(dataRate); //Test and intialize the MMA8452
}

void loop()
{
  int accelCount[3];  // Stores the 12-bit signed value
  readAccelData(accelCount);  // Read the x/y/z adc values
  
  lcd_key = read_LCD_buttons();
  static int value = 0;
  lcd.setCursor(0,0);
  lcd.print("Tilt degrees: ");
  lcd.setCursor(13,0);
  lcd.print(value); // displays the count
if(lcd_key == 1)
  {
    value = constrain(value+1,-30,30);  // I only wanted it to count from (-30)-(+30) and back
  }
else if (lcd_key == 2)
  {
    value = constrain(value-1,-30,30);  // I only wanted it to count from (-30)-(+30_)and back
  }
else if (lcd_key == 4)
  {
    // Now we'll calculate the accleration value into actual g's
  float accelG[3];  // Stores the real accel value in g's
  for (int i = 0 ; i < 3 ; i++)
  {
    accelG[i] = (float) accelCount[i] / ((1<<12)/(2*GSCALE));  // get actual g value, this depends on scale being set
  }
   //Y Axis
   accel_angle_y = asin(accelG[1])*57.2957795; 
   if (accel_angle_y % value == 0) {
    rotateDeg(1, .5);
  }
  delay(150);   
  lcd.setCursor(1,1);
  lcd.print("Beam angle: ");
  lcd.setCursor(12,1);
  lcd.print(accel_angle_y); // displays the count
  delay(150);
  }
}

void readAccelData(int *destination)
{
  byte rawData[6];  // x/y/z accel register data stored here
  readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array
  // Loop to calculate 12-bit ADC and g value for each axis
  for(int i = 0; i < 3 ; i++)
  {
    int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
    gCount >>= 4; //The registers are left align, here we right align the 12-bit integer

    // If the number is negative, we have to make it so manually (no 12-bit data type)
    if (rawData[i*2] > 0x7F)
    {  
      gCount = ~gCount + 1;
      gCount *= -1;  // Transform into negative 2's complement #
    }
    destination[i] = gCount; //Record this gCount into the 3 int array
  }
}

// Initialize the MMA8452 registers 
void initMMA8452(byte dataRate)
{
  byte c = readRegister(WHO_AM_I);  // Read WHO_AM_I register
  if (c == 0x2A) // WHO_AM_I should always be 0x2A
  {  
    Serial.println(c);
    Serial.println("MMA8452Q is online...");
  }
  else
  {
    Serial.print("Could not connect to MMA8452Q: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }

  MMA8452Standby();  // Must be in standby to change registers

  // Set up the full scale range to 2, 4, or 8g.
  byte fsr = GSCALE;
  if(fsr > 8) fsr = 8; //Easy error check
  fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
  //1000 -> 0010
  writeRegister(XYZ_DATA_CFG, fsr);//page 22.

  // Setup the 3 data rate bits, from 0 to 7
  writeRegister(CTRL_REG1, readRegister(CTRL_REG1) & ~(0x38));
  if (dataRate <= 7)
    writeRegister(CTRL_REG1, readRegister(CTRL_REG1) | (dataRate << 3));  
  //The default data rate is 800Hz and we don't modify it in this example code

  MMA8452Active();  // Set to active to start reading
}

// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
void MMA8452Standby()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
}

// Sets the MMA8452 to active mode. Needs to be in this mode to output data
void MMA8452Active()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
}

// Read bytesToRead sequentially, starting at addressToRead into the dest byte array
void readRegisters(byte addressToRead, int bytesToRead, byte * dest)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

    Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default

  while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect

  for(int x = 0 ; x < bytesToRead ; x++)
    dest[x] = Wire.read();    
}

// Read a single byte from addressToRead and return it as a byte
byte readRegister(byte addressToRead)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

    Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default

  while(!Wire.available()) ; //Wait for the data to come back
  return Wire.read(); //Return this one byte
}

// Writes a single byte (dataToWrite) into addressToWrite
void writeRegister(byte addressToWrite, byte dataToWrite)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToWrite);
  Wire.write(dataToWrite);
  Wire.endTransmission(); //Stop transmitting
}


void rotateDeg(float deg, float speed){ 
  //rotate a specific number of degrees (negitive for reverse movement)
  //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
  int dir = (deg > 0)? HIGH:LOW;
  digitalWrite(DIR_PIN,dir); 

  int steps = abs(deg)*(1/0.225);
  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){ 
    digitalWrite(STEP_PIN, HIGH); 
    delayMicroseconds(usDelay); 

    digitalWrite(STEP_PIN, LOW); 
    delayMicroseconds(usDelay); 
  } 
}

// declair funtion to read the buttons

int read_LCD_buttons()
{
adc_key_in = analogRead(0);      // read the value from the sensor

// For V1.1 us this threshold
if (adc_key_in < 250)  return btnUP; 
if (adc_key_in < 450)  return btnDOWN; 
if (adc_key_in < 850)  return btnSELECT;
}

ball_plate.ino (6.76 KB)

My advice is to simplify things to test the LCD.

Write yourself a really "lite" sketch just to get the LCD sorted, make sure it's displaying a sort of "hello world" message. In those "ifs" you could do a print to the LCD to prove the button is being detected.

if(lcd_key == 1)
  {
    lcd.print("button 1")
  }

Right now, it's really difficult to debug. So get the LCD working by itself, is my suggestion.....

when i strip down the code and only run the lcd code it works fine, its just when i start adding the accelerometer code it stops displaying text on the lcd. it might be a conflict when initializing things but for the life of me i cannot figure where the problem is

By the way, seeing as you have Serial.begin() in setup, use the serial monitor to help you debug. Stick a Serial.println("xxxxxx"); in appropriate places (with an appropriate message) to show you where the flow has gone.

That's especially useful with ifs, since you can see if you're in the top part of the if or the else, for example. Use it to print variables' values.

By the way I see this:

 {
    Serial.print("Could not connect to MMA8452Q: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }

Have you got your monitor open to see if you're getting this message? It might be stuck there due to that while(1) endless loop.

bullitt3123: when i strip down the code and only run the lcd code it works fine,

If you knew that before, you should have said so...

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Your other thread deleted.

  • Moderator

[quote author=Nick Gammon link=msg=1988794 date=1417763212] Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Your other thread deleted.

  • Moderator

[/quote]I actually tried to post on the other thread "I suggest you delete this post before a moderator sees it" Seems I was too late :)

    Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default

while(!Wire.available()) ; //Wait for the data to come back
 return Wire.read(); //Return this one byte

Wire.requestFrom does not return until data has come back, or there is an error.

http://www.gammon.com.au/i2c

Ditto for here:

    Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default

  while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect

  for(int x = 0 ; x < bytesToRead ; x++)
    dest[x] = Wire.read();

If the device doesn’t respond that will go into an infinite loop.


What do your serial prints tell you?

JimboZA, thanks for the help it seems to have solved the problem. i just need to fix a few bugs

bullitt3123: it seems to have solved the problem

What has? I didn't give a solution, just a means of helping debug. But if that helped you debug, that's cool.

I actually tried to post on the other thread "I suggest you delete this post before a moderator sees it" Seems I was too late :)

The Moderator sees all.

... it seems to have solved the problem ...

http://en.wikipedia.org/wiki/Knights_who_say_Ni

The Knights happen to have a weakness in that a number of words, when spoken to them, have the same effect on them as their saying "Ni" has on others. The only one of these words that is revealed in the film is the word "it",

Be careful using the word "it".

[quote author=Nick Gammon link=msg=1988862 date=1417767705] Be careful using the word "it". [/quote]Unless extolling the virtues of a shrubbery. Then it's fine.

KenF: Unless extolling the virtues of a shrubbery. Then it's fine.

Especially if you have two with a path in between and a nice two-level effect.