Troubleshooting I2C communication between Arduino and sensor

Thread Starter

Adam Tekle

Joined Apr 14, 2019
2
Hello everyone, new member here and this is my first time posting.

I've been trying to get any signs of life from a sensor that I am trying to communicate with and Arduino
Sensor - AMS AS5601 Position Sensor, bought here (Datasheet)
Arduino - Mega 2560

I have currently tried using a I2C "scanner" that works by calling each address and looking for a acknowledge bit. However, I never get a acknowledge. I've also tried writing my own code that calls its address and then writes to move the header to a status register, but before I can even get to reading the register, I get an error because there was no acknowledge bit.
-- Code --
Code:
void setup() {
  Serial.begin (115200);
  while (!(Serial.available() > 0))
    {
    }

  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;

  Wire.begin();
  for (byte i = 8; i < 128; i++)
  {
    Serial.print ("Address: ");
    Serial.println (i);
 
 
    Wire.beginTransmission (i);
    byte result = Wire.endTransmission ();
    if (result == 0)
      {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (100);  // maybe unneeded?
      } // end of good response
      else {Serial.print ("Failed Response. Code "); Serial.println (result);}
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup
Output :
Code:
I2C scanner. Scanning ...
Address: 8
Failed Response. Code 2
Address: 9
Failed Response. Code 2
Address: 10
Failed Response. Code 2
Address: 11
Failed Response. Code 2
Address: 12
Failed Response. Code 2
Address: 13
Failed Response. Code 2
Address: 14
Failed Response. Code 2
Address: 15
Failed Response. Code 2
Address: 16
Failed Response. Code 2
Address: 17
Failed Response. Code 2
Address: 18
Failed Response. Code 2
Address: 19
Failed Response. Code 2
Address: 20
Failed Response. Code 2
Address: 21
Failed Response. Code 2
Address: 22
Failed Response. Code 2
Address: 23
Failed Response. Code 2
Address: 24
Failed Response. Code 2
Address: 25
Failed Response. Code 2
Address: 26
Failed Response. Code 2
Address: 27
Failed Response. Code 2
Address: 28
Failed Response. Code 2
Address: 29
Failed Response. Code 2
Address: 30
Failed Response. Code 2
Address: 31
Failed Response. Code 2
Address: 32
Failed Response. Code 2
Address: 33
Failed Response. Code 2
Address: 34
Failed Response. Code 2
Address: 35
Failed Response. Code 2
Address: 36
Failed Response. Code 2
Address: 37
Failed Response. Code 2
Address: 38
Failed Response. Code 2
Address: 39
Failed Response. Code 2
Address: 40
Failed Response. Code 2
Address: 41
Failed Response. Code 2
Address: 42
Failed Response. Code 2
Address: 43
Failed Response. Code 2
Address: 44
Failed Response. Code 2
Address: 45
Failed Response. Code 2
Address: 46
Failed Response. Code 2
Address: 47
Failed Response. Code 2
Address: 48
Failed Response. Code 2
Address: 49
Failed Response. Code 2
Address: 50
Failed Response. Code 2
Address: 51
Failed Response. Code 2
Address: 52
Failed Response. Code 2
Address: 53
Failed Response. Code 2
Address: 54
Failed Response. Code 2
Address: 55
Failed Response. Code 2
Address: 56
Failed Response. Code 2
Address: 57
Failed Response. Code 2
Address: 58
Failed Response. Code 2
Address: 59
Failed Response. Code 2
Address: 60
Failed Response. Code 2
Address: 61
Failed Response. Code 2
Address: 62
Failed Response. Code 2
Address: 63
Failed Response. Code 2
Address: 64
Failed Response. Code 2
Address: 65
Failed Response. Code 2
Address: 66
Failed Response. Code 2
Address: 67
Failed Response. Code 2
Address: 68
Failed Response. Code 2
Address: 69
Failed Response. Code 2
Address: 70
Failed Response. Code 2
Address: 71
Failed Response. Code 2
Address: 72
Failed Response. Code 2
Address: 73
Failed Response. Code 2
Address: 74
Failed Response. Code 2
Address: 75
Failed Response. Code 2
Address: 76
Failed Response. Code 2
Address: 77
Failed Response. Code 2
Address: 78
Failed Response. Code 2
Address: 79
Failed Response. Code 2
Address: 80
Failed Response. Code 2
Address: 81
Failed Response. Code 2
Address: 82
Failed Response. Code 2
Address: 83
Failed Response. Code 2
Address: 84
Failed Response. Code 2
Address: 85
Failed Response. Code 2
Address: 86
Failed Response. Code 2
Address: 87
Failed Response. Code 2
Address: 88
Failed Response. Code 2
Address: 89
Failed Response. Code 2
Address: 90
Failed Response. Code 2
Address: 91
Failed Response. Code 2
Address: 92
Failed Response. Code 2
Address: 93
Failed Response. Code 2
Address: 94
Failed Response. Code 2
Address: 95
Failed Response. Code 2
Address: 96
Failed Response. Code 2
Address: 97
Failed Response. Code 2
Address: 98
Failed Response. Code 2
Address: 99
Failed Response. Code 2
Address: 100
Failed Response. Code 2
Address: 101
Failed Response. Code 2
Address: 102
Failed Response. Code 2
Address: 103
Failed Response. Code 2
Address: 104
Failed Response. Code 2
Address: 105
Failed Response. Code 2
Address: 106
Failed Response. Code 2
Address: 107
Failed Response. Code 2
Address: 108
Failed Response. Code 2
Address: 109
Failed Response. Code 2
Address: 110
Failed Response. Code 2
Address: 111
Failed Response. Code 2
Address: 112
Failed Response. Code 2
Address: 113
Failed Response. Code 2
Address: 114
Failed Response. Code 2
Address: 115
Failed Response. Code 2
Address: 116
Failed Response. Code 2
Address: 117
Failed Response. Code 2
Address: 118
Failed Response. Code 2
Address: 119
Failed Response. Code 2
Address: 120
Failed Response. Code 2
Address: 121
Failed Response. Code 2
Address: 122
Failed Response. Code 2
Address: 123
Failed Response. Code 2
Address: 124
Failed Response. Code 2
Address: 125
Failed Response. Code 2
Address: 126
Failed Response. Code 2
Address: 127
Failed Response. Code 2
Done.
Found 0 device(s).
Note: this scanner works when looking for another Arduino when it's set as a slave.

My questions are
1.) Is my code correct?
2.)Does the sensor need anything else to communicate?
3.) What else can I do to troubleshoot?
 
Last edited:

be80be

Joined Jul 5, 2008
2,072
Its dum. Why are you scaning it for address
It has only one its listed in the datasheet 0x36
Thats the slave address.
 

Thread Starter

Adam Tekle

Joined Apr 14, 2019
2
I tried that too. That was to just to check
Code: This moves header to status register, and then tries to read it
Code:
#include <Wire.h>
  byte deviceAddressReading = 01101101;
  byte deviceAddressWriting = 0110110;
  byte statusRegisterAddress = 00001011;
// the setup function runs once when you press reset or power the board
void setup() {
//  Wire.begin();
  delay(1500);
  Wire.begin();
//  I2c.setSpeed(0);
// I2c.pullup(1);
//  I2c.timeOut(3000);
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  while(!(Serial.available() > 0)) { }

  Serial.println("5s till communication with sensor");
  delay(1000);
  Serial.println("4s till communication with sensor");
  delay(1000);
  Serial.println("3s till communication with sensor");
  delay(1000);
  Serial.println("2s till communication with sensor");
  delay(1000);
  Serial.println("1s till communication with sensor");
  delay(1000);
  Serial.println("Communicating. Err Code For Head: ");
  Wire.beginTransmission(108);
  Wire.write(statusRegisterAddress);
  Serial.println(String(Wire.endTransmission()));
  Serial.println(String(Wire.requestFrom(109,1,true)));
  Serial.println(String(Wire.read()));


}

This is what I get:
Code:
5s till communication with sensor
4s till communication with sensor
3s till communication with sensor
2s till communication with sensor
1s till communication with sensor
Communicating. Err Code For Head:
2
0
-1
 

AlbertHall

Joined Jun 4, 2014
12,268
It sounds like there is a problem with the hardware.
1. Make sure that the two clock pins are connected together and that you have the correct pin.
2. Likewise for the data pins.
3. Make sure that you have pull-up resistors on both clock and data lines - typically 4.7k
4. Start with short wires between the two devices.
 

be80be

Joined Jul 5, 2008
2,072
I think I'd try this
Code:
#include <Arduino.h>
#include <AS5601.h>


AS5601 Sensor;


void setup()
{
    delay( 1000 );
    Serial.begin( 115200 );
    Serial.println( F("Angle Measurement with AS5601") );
}


void loop()
{
    Serial.print( F("Magnitude: ") );
    Serial.print( Sensor.getMagnitude() );

    Serial.print( F(" | Raw angle: ") );
    Serial.print( Sensor.getRawAngle() );

    Serial.print( F(" | Clean angle: ") );
    Serial.print( Sensor.getAngle() );

    if ( Serial.read() == '0' )
    {
        Sensor.setZeroPosition();
        Serial.print( F(" | Zero position set!") );
    }

    Serial.println();

    delay( 50 );
}
You can down load the AS5601 Library for Arduino here https://github.com/bitfasching/AS5601
Here the header
Code:
/**
* AS5601 Driver
*
* Arduino Library
* for AS5601 Magnet Rotary Sensor
*
* License: BSD 3-Clause
*
* Nick Schwarzenberg,
* 06/2016, v0.1.0
*/


// include these dependencies in your top-level .ino!
#include <Arduino.h>
#include <Wire.h>

// prevent redefinitions
#ifndef AS5601_driver
#define AS5601_driver


class AS5601
{
    public:

        /* :: Configuration :: */


        // 7-bit device address
        unsigned char address = 0x36;

        // 8-bit register addresses
        static struct ByteRegister {
            static const unsigned char
            ZMCO = 0x00,
            ABN = 0x09,
            PUSHTHR = 0x0A,
            STATUS = 0x0B,
            AGC = 0x1A,
            BURN = 0xFF;
        } ByteRegister;

        // 16-bit register start (high byte) addresses
        static struct WordRegister {
            static const unsigned char
            ZPOS = 0x01,
            CONF = 0x03,
            RAWANGLE = 0x0C,
            ANGLE = 0x0E,
            MAGNITUDE = 0x1B;
        } WordRegister;

        // initialization
        AS5601()
        {
            // host I2C bus as master in the default I2C channel
            wireChannel = &Wire;
            wireChannel->begin();
        }

        // initialization with explicit I2C channel
        AS5601(TwoWire *i2cChannel)
        {
            // host I2C bus as master in the passed channel
            wireChannel = i2cChannel;
            wireChannel->begin();
        }


        /* :: Low-Level Access :: */


        // low-level: read one byte from an 8-bit register
        unsigned char readRaw8( unsigned char registerAddress )
        {
            // send START for I2C frame to the AS5601
            wireChannel->beginTransmission( this->address );

            // send register address
            wireChannel->write( registerAddress );

            // flush, but do not release bus (no STOP)
            wireChannel->endTransmission( false );

            // request one byte as response from the AS5601, release and wait
            // (casting is necessary due to similar declarations of .requestFrom)
            wireChannel->requestFrom( (uint8_t) this->address, (uint8_t) 1, (uint8_t) true );

            // return response
            return wireChannel->read();
        }

        // low-level: read two bytes as 16-bit word from two 8-bit registers
        unsigned int readRaw16( unsigned char registerStartAddress )
        {
            // get high byte, then low byte
            unsigned char highByte = this->readRaw8( registerStartAddress );
            unsigned char lowByte = this->readRaw8( registerStartAddress + 1 );

            // combine to 16-bit word
            return word( highByte, lowByte );
        }


        // low-level: write one byte to an 8-bit register
        void writeRaw8( unsigned char registerAddress, unsigned char value )
        {
            // send START for I2C frame to the AS5601
            wireChannel->beginTransmission( this->address );

            // send register address and value
            wireChannel->write( registerAddress );
            wireChannel->write( value );

            // flush and release (STOP)
            wireChannel->endTransmission( true );
        }

        // low-level: write 16-bit word as two bytes to two 8-bit registers
        void writeRaw16( unsigned char registerStartAddress, unsigned int value )
        {
            // send high byte, then low byte
            this->writeRaw8( registerStartAddress, (unsigned char) highByte( value ) );
            this->writeRaw8( registerStartAddress + 1, (unsigned char) lowByte( value ) );
        }



        /* :: Higher-Level Methods :: */


        // query status to find out if magnet is detected
        bool magnetDetected()
        {
            // query status register
            unsigned char status = this->readRaw8( AS5601::ByteRegister::STATUS );

            // return true if bit 5 is set
            return bitRead( status, 5 ) == 1 ? true : false;
        }

        // get current magnetic magnitude (12 bit)
        unsigned int getMagnitude()
        {
            // read and return two-byte magnitude
            return this->readRaw16( AS5601::WordRegister::MAGNITUDE );
        }

        // get current gain of AGC (8 bit)
        unsigned char getGain()
        {
            // read and return one-byte gain
            return this->readRaw8( AS5601::ByteRegister::AGC );
        }

        // get raw angle (12 bit)
        unsigned int getRawAngle()
        {
            // read and return two-byte raw angle
            return this->readRaw16( AS5601::WordRegister::RAWANGLE );
        }

        // set zero-position to specified raw angle (12 bit)
        void setZeroPosition( unsigned int rawAngle )
        {
            // send position setting command
            this->writeRaw16( AS5601::WordRegister::ZPOS, rawAngle );
        }

        // convenience method: read current raw angle and pass it to .setZeroPosition(rawAngle)
        void setZeroPosition() { this->setZeroPosition( this->getRawAngle() ); }

        // set angle resolution (affecting output value range and update speed)
        void setResolution( unsigned int angleSteps )
        {
            char power = -1;

            // coerce angle steps to supported values (8, 16, 32, …, 2048)
            angleSteps = min( max( angleSteps, 8 ), 2048 );

            // find dual logarithm (2^power >= angleSteps)
            // (by comparing increasing powers of two with angleSteps)
            while ( ( 1 << ++power ) < angleSteps );

            // send ABN setting command (-3 (2^3 = 8) shifts the powers 3…11 (for 8…2048) to 0…8)
            this->writeRaw8( AS5601::ByteRegister::ABN, power-3 );
        }

        // get zero-adjusted and filtered angle (12 bit)
        unsigned int getAngle()
        {
            // read and return two-byte clean angle
            return this->readRaw16( AS5601::WordRegister::ANGLE );
        }

    private:

        TwoWire *wireChannel;
};
 
Top