arduino motor shield V2.3 - 3 DC motors and another I2C devi

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

arduino motor shield V2.3 - 3 DC motors and another I2C devi

Post by prathapchandra »

I have an I2C based touchpad from which I am extracting button pressed information, and this controls my car rear view mirror.

the issue i am facing is, when my control enter switch statement, the system hangs, serial com hangs up, I2C bus remains high voltage.
below is the code:

Code: Select all

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_MotorShield.h>
#include <LocateZone.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
Adafruit_DCMotor *Motor2 = AFMS.getMotor(2);
Adafruit_DCMotor *Motor3 = AFMS.getMotor(3);


#define DEV_Addr 0X3  //Device I2C address in Hex

const ZONE_T virtualZone[ VIRTUAL_ZONE_MAX ] = {
  POLYGON_PROCESS,              /* process type  */
  4,  
  708, 1140,                  //up button
  1228, 1889,  
  187, 1889,
  187, 1889,
    
    
  /* VZ2 defaults  */
  POLYGON_PROCESS,              /* process type  */
  4,     
  708,  907,                   //down button
  188,  158,         
  1229,  158, 
  1229,  158,   
  
  /* VZ3 defaults  */
  POLYGON_PROCESS,              /* process type  */
  4,       
  789, 1023,                  //left button
  1310, 275,  
  1310, 1772,       
  1310, 1772,       
 
  /* VZ4 defaults  */
  POLYGON_PROCESS,      /* process type  */
  4,     
  106,  1771,                 //right button
  305,  1023,        
  106,  275,  
  106,  275,  

  /* VZ5 defaults  */
  POLYGON_PROCESS,              /* process type  */
  4,       
  1554, 157,                  //main up
  1926, 157,  
  1554, 941, 
  1926, 941,         
 
  /* VZ6 defaults  */
  POLYGON_PROCESS,      /* process type  */
  4,     
  1555,  1106,                 //main down
  1927,  1106,        
  1555,  1889,
  1927,  1889,  

  
};

unsigned short combinedx = 0;                                                   //variables to hold combined values(MSB,LSB) of the X,Y and F
unsigned short combinedy = 0;
unsigned short combinedz = 0;
float  X_LOC, Y_LOC,F_FORCE;                                                    //Location(mm) and Force(N) values
byte mySensVals[6];                                                             //To store the read I2C buffer data
int Sensitivity = 100, zoneNumber=0;
int sensorValue1 = analogRead(A0);
int sensorValue2 = analogRead(A1);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.3V):
float m1pos;
float m2pos;
// print out the value you read:

void setup() 
{
  Serial.begin(9600);
  Wire.begin();
  AFMS.begin(64000);  // create with the default frequency 64KHz
  Motor1->setSpeed(200);
  Motor1->run(RELEASE);
  Motor2->setSpeed(200);
  Motor2->run(RELEASE);
  Motor3->setSpeed(200);
  Motor3->run(RELEASE);
  zoneNumber = 0;

  #if 0
  TWBR = ((F_CPU / 400000l) - 16) / 2; // Change the i2c clock from 100KHz to 400KHz
  #endif
}


void loop()
{
         zoneNumber=0;
         
         ReadBuffer(); 
         GetValues();
         delay(500);
             
              for (int idx = 0; idx < 6; idx++)
              {
                    if ( zoneNumber == 0 )  /* still no zone found ?  Then test the next VBZ  */
                    {
                                 if (IsPointInPolygon( idx ) == true)
                                {
                                    zoneNumber = idx + 1;
                                }
                    }
                    else
                    break;    /* exit the outer loop.  A zone has been found  */
              }

         Serial.print("Zone Number : ");
         Serial.println(zoneNumber);
         A2DC();
                           
                             switch (zoneNumber)
                              {
                                case 1:
                                     Motor2->run(FORWARD);            // turn on motor  
                                     delay(1000);
                                     Motor2->run(RELEASE);
                                     break;
                          
                                case 2:
                                     Motor2->run(BACKWARD);            // turn on motor  
                                     delay(1000);
                                     Motor2->run(RELEASE);
                                     break;  
                           
                                case 3:
                                     Motor1->run(BACKWARD);            // turn on motor  
                                     delay(1000);
                                     Motor2->run(RELEASE);
                                     break;                
                          
                                case 4:
                                     Motor1->run(FORWARD);            // turn on motor  
                                     delay(1000);
                                     Motor2->run(RELEASE);
                                     break; 
                          
                                case 5:
                          
                                     Motor3->run(FORWARD);            // turn on motor  
                                     delay(1000);
                                     Motor3->run(RELEASE);
                                     break;          
                          
                                case 6:
                          
                                     Motor3->run(BACKWARD);            // turn on motor  
                                     delay(1000);
                                     Motor3->run(RELEASE);
                                     break;     

                                                
                              }

                                                          
}

// #########################################################################
// determine if point is in the triangle
// #########################################################################

/*******************************************************************************
* This function determines whether measured points are in a Polygon or not
*
* \param        VBZidx  index to the VBZ being considered
* \retval       BOOL            True if point lies in polygon
*                               False if it doesn't
*******************************************************************************/
static bool IsPointInPolygon( unsigned char VBZidx )
{
    unsigned char iIdx;   
    unsigned char jIdx;
    unsigned char vertCount;
    bool tp_Presence = false;
    
    /* find the number of verticies in this poly less 1*/
    vertCount = (unsigned char)virtualZone[VBZidx].polyCount;
    /* preset the jIdx to the end of the array of verticies  */
    jIdx = vertCount - 1U;
    
    for (iIdx = 0; iIdx < vertCount; iIdx++ )
    {
        if ((( virtualZone[VBZidx].vertex[iIdx].y <= combinedy ) &&
             ( virtualZone[VBZidx].vertex[jIdx].y >= combinedy )) ||   
            (( virtualZone[VBZidx].vertex[jIdx].y <= combinedy ) &&
             ( virtualZone[VBZidx].vertex[iIdx].y >= combinedy )))
        {
            if (( virtualZone[VBZidx].vertex[iIdx].x + (float)( combinedy - virtualZone[VBZidx].vertex[iIdx].y) / /* PRQA S 3395, 3390, 1800, 4393 */
                                    (float)(virtualZone[VBZidx].vertex[jIdx].y - virtualZone[VBZidx].vertex[iIdx].y) *    /*PRQA S 1800, 4393 */  
                                    (virtualZone[VBZidx].vertex[jIdx].x - virtualZone[VBZidx].vertex[iIdx].x))  <=  combinedx)/* PRQA S 1802 */
            {
                tp_Presence ^= true;  /* an odd count leaves this = TRUE */
            }
            else { /* MISRA compliance  */}
        }
        else { /* MISRA compliance  */}
        
        jIdx = iIdx;  /* move down the array of verticies */
    }
        
    return (tp_Presence);
}


// #########################################################################
// Read the Data buffer from the POC over I2C
// #########################################################################
void ReadBuffer()  //Read the data buffer from the SwitchPack using i2c
{ 
   Wire.beginTransmission(DEV_Addr);     // transmit to device
   Wire.write(byte(0x10));               // contains data buffer
   Wire.write(byte(0x20));               // contains data buffer
   Wire.endTransmission();               // stop transmitting
    
   Wire.requestFrom(DEV_Addr, 6);    // request 6 bytes from slave device

   // receive reading from sensor
   while(Wire.available())          // slave may send less than requested
   { 
     int ind;
        for (ind =0; ind <= 6; ind++)
        {
          mySensVals[ind] = Wire.read();
        }
   }
}

// #########################################################################
// Get the x, y, F values from the read buffer data
// #########################################################################
void GetValues()  
{
   unsigned char xhi = mySensVals[0];     //Combine the MSB abd LSB data bytes to get the X value
   unsigned char xlo = mySensVals[1];
   combinedx = xhi;
   combinedx = combinedx<<8;
   combinedx |=xlo;

   Serial.println(combinedx);
   
   unsigned char yhi = mySensVals[2];     //Combine the MSB abd LSB data bytes to get the Y value
   unsigned char ylo = mySensVals[3];
   combinedy = yhi;
   combinedy = combinedy<<8;
   combinedy |=ylo;
   Serial.println(combinedy);
   
   unsigned char zhi = mySensVals[4];     //Combine the MSB abd LSB data bytes to get the Z value
   unsigned char zlo = mySensVals[5];
   combinedz = zhi;
   combinedz = combinedz<<8;
   combinedz |=zlo;
   Serial.println(combinedz);
   
}


//##########################################################################
//Read mirror Position
//##########################################################################

void A2DC()
{
  int sensorValue1 = analogRead(A0);
  int sensorValue2 = analogRead(A1);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.3V):
  float voltage1 = sensorValue1 * (3.3 / 1023.0);
  float voltage2 = sensorValue2 * (3.3 / 1023.0);
  // print out the value you read:
  Serial.println(voltage1);
  Serial.println(voltage2);
  Serial.println();
}
clearly, there seems to be I2C bus contention.
any insights is deeply appreciated

thank you
Prathap

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

Have you verified that the motor shield and your other device both function independently? I looks like your other device uses address 0x03. The Motor shield defaults to addresses 0x60 and 0x70. There is no way to address it to 0x03.

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

yes, both function independently very well.
I was using Arduino Zero, while I reported this observation.

meanwhile, I tried with Leonardo and a UNO, the system doesn't hang with these two boards, however, the zone values have an error.
hence control is not as intended press

thanks for responding so quickly

thank you
Prathap

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

Try running the i2c scanner. That will show if all devices are responding normally on the bus.

https://playground.arduino.cc/Main/I2cScanner

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

the I2C scanner is identifying three I2C devices and below is the message on the serial comm


Scanning...
I2C device found at address 0x03 !
I2C device found at address 0x60 !
I2C device found at address 0x70 !
done

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

How long is your i2c bus? The UNO is 5v, while the Zero is 3.3v. The Zero will be more sensitive to bus capacitance and noise.

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

Am facing two issues as of now
1. With Arduino Zero + motor shield + I2C device - system hangs when I try to run the motors
2. With Arduino Uno or Leonardo +motor shield + I2C device - the system processes the zone information incorrectly.

I am welcome to suggestions to make this work, what I thought was a simple task is taking up a lot of time.

thank you
Prathap

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

the wire length is about 15 inches approximately.

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

I cut short the I2C SDA and SCL lines to about 8 inches approximately.
still the same issue

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

1. With Arduino Zero + motor shield + I2C device - system hangs when I try to run the motors
The Zero is going to be more sensitive to line capacitance and noise. 8" is generally not a problem. But motors are notorious sources of noise. Some details on the motors you are using and photos showing your wiring may be helpful.
2. With Arduino Uno or Leonardo +motor shield + I2C device - the system processes the zone information incorrectly.
Can you explain what you mean by that? It might help to post the zone processing code you are referring to.

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

the issue is seen even without connecting the motors. there three motors though.
the code I posted in my first comment has the zone calculation function as well.

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

Your analog readings are assuming a 3.,3v voltage reference. The default on the UNO is 5v.

Code: Select all

void A2DC()
{
  int sensorValue1 = analogRead(A0);
  int sensorValue2 = analogRead(A1);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.3V):
  float voltage1 = sensorValue1 * (3.3 / 1023.0);
  float voltage2 = sensorValue2 * (3.3 / 1023.0);
  // print out the value you read:
  Serial.println(voltage1);
  Serial.println(voltage2);
  Serial.println();
}

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

yes, please ignore that, those values are for limiting values, am not using them yet until I can get correct zone values and be able to control the motor as intended.

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by adafruit_support_bill »

Then please post the relevant bit of code.

User avatar
prathapchandra
 
Posts: 16
Joined: Thu Sep 03, 2015 7:32 am

Re: arduino motor shield V2.3 - 3 DC motors and another I2C

Post by prathapchandra »

found a fix for setup 1 - Zero + Motor Shield + I2C device

Code: Select all

/*************************************************** 
  This is a library for our Adafruit 16-channel PWM & Servo driver

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These displays use I2C to communicate, 2 pins are required to  
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Adafruit_MS_PWMServoDriver.h>
#include <Wire.h>

 #define WIRE Wire



Adafruit_MS_PWMServoDriver::Adafruit_MS_PWMServoDriver(uint8_t addr) {
  _i2caddr = addr;
}

void Adafruit_MS_PWMServoDriver::begin(void) {
 WIRE.begin();
 reset();
}


void Adafruit_MS_PWMServoDriver::reset(void) {
 write8(PCA9685_MODE1, 0x0);
}

void Adafruit_MS_PWMServoDriver::setPWMFreq(float freq) {
  //Serial.print("Attempting to set freq ");
  //Serial.println(freq);
  
  freq *= 0.9;  // Correct for overshoot in the frequency setting (see issue #11).

  float prescaleval = 25000000;
  prescaleval /= 4096;
  prescaleval /= freq;
  prescaleval -= 1;
  //Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
  uint8_t prescale = floor(prescaleval + 0.5);
  //Serial.print("Final pre-scale: "); Serial.println(prescale);  
  
  uint8_t oldmode = read8(PCA9685_MODE1);
  uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
  write8(PCA9685_MODE1, newmode); // go to sleep
  write8(PCA9685_PRESCALE, prescale); // set the prescaler
  write8(PCA9685_MODE1, oldmode);
  delay(5);
  write8(PCA9685_MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
                                          // This is why the beginTransmission below was not working.
  //  Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}

void Adafruit_MS_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
  //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);

  WIRE.beginTransmission(_i2caddr);
  WIRE.write(byte(LED0_ON_L+4*num));
  WIRE.write(byte(on));
  WIRE.write(byte(on>>8));
  WIRE.write(byte(off));
  WIRE.write(byte(off>>8));

  WIRE.endTransmission();
}

uint8_t Adafruit_MS_PWMServoDriver::read8(uint8_t addr) {
  WIRE.beginTransmission(_i2caddr);

  WIRE.write(byte(addr));

  WIRE.endTransmission();

  WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)1);

  return WIRE.read();

}

void Adafruit_MS_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
  WIRE.beginTransmission(_i2caddr);
  WIRE.write(byte(addr));
  WIRE.write(byte(d));


  WIRE.endTransmission();
}
all wire.write values should be "byte"

do you know why this solved the issue?

thank you
Prathap

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”