Troubleshooting I2C communication between Arduino and sensor

Discussion in 'Embedded Systems and Microcontrollers' started by Adam Tekle, Apr 14, 2019.

  1. Adam Tekle

    Thread Starter New Member

    Apr 14, 2019
    2
    0
    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 (Text):
    1. void setup() {
    2.   Serial.begin (115200);
    3.   while (!(Serial.available() > 0))
    4.     {
    5.     }
    6.  
    7.   Serial.println ();
    8.   Serial.println ("I2C scanner. Scanning ...");
    9.   byte count = 0;
    10.  
    11.   Wire.begin();
    12.   for (byte i = 8; i < 128; i++)
    13.   {
    14.     Serial.print ("Address: ");
    15.     Serial.println (i);
    16.  
    17.  
    18.     Wire.beginTransmission (i);
    19.     byte result = Wire.endTransmission ();
    20.     if (result == 0)
    21.       {
    22.       Serial.print ("Found address: ");
    23.       Serial.print (i, DEC);
    24.       Serial.print (" (0x");
    25.       Serial.print (i, HEX);
    26.       Serial.println (")");
    27.       count++;
    28.       delay (100);  // maybe unneeded?
    29.       } // end of good response
    30.       else {Serial.print ("Failed Response. Code "); Serial.println (result);}
    31.   } // end of for loop
    32.   Serial.println ("Done.");
    33.   Serial.print ("Found ");
    34.   Serial.print (count, DEC);
    35.   Serial.println (" device(s).");
    36. }  // end of setup
    Output :
    Code (Text):
    1. I2C scanner. Scanning ...
    2. Address: 8
    3. Failed Response. Code 2
    4. Address: 9
    5. Failed Response. Code 2
    6. Address: 10
    7. Failed Response. Code 2
    8. Address: 11
    9. Failed Response. Code 2
    10. Address: 12
    11. Failed Response. Code 2
    12. Address: 13
    13. Failed Response. Code 2
    14. Address: 14
    15. Failed Response. Code 2
    16. Address: 15
    17. Failed Response. Code 2
    18. Address: 16
    19. Failed Response. Code 2
    20. Address: 17
    21. Failed Response. Code 2
    22. Address: 18
    23. Failed Response. Code 2
    24. Address: 19
    25. Failed Response. Code 2
    26. Address: 20
    27. Failed Response. Code 2
    28. Address: 21
    29. Failed Response. Code 2
    30. Address: 22
    31. Failed Response. Code 2
    32. Address: 23
    33. Failed Response. Code 2
    34. Address: 24
    35. Failed Response. Code 2
    36. Address: 25
    37. Failed Response. Code 2
    38. Address: 26
    39. Failed Response. Code 2
    40. Address: 27
    41. Failed Response. Code 2
    42. Address: 28
    43. Failed Response. Code 2
    44. Address: 29
    45. Failed Response. Code 2
    46. Address: 30
    47. Failed Response. Code 2
    48. Address: 31
    49. Failed Response. Code 2
    50. Address: 32
    51. Failed Response. Code 2
    52. Address: 33
    53. Failed Response. Code 2
    54. Address: 34
    55. Failed Response. Code 2
    56. Address: 35
    57. Failed Response. Code 2
    58. Address: 36
    59. Failed Response. Code 2
    60. Address: 37
    61. Failed Response. Code 2
    62. Address: 38
    63. Failed Response. Code 2
    64. Address: 39
    65. Failed Response. Code 2
    66. Address: 40
    67. Failed Response. Code 2
    68. Address: 41
    69. Failed Response. Code 2
    70. Address: 42
    71. Failed Response. Code 2
    72. Address: 43
    73. Failed Response. Code 2
    74. Address: 44
    75. Failed Response. Code 2
    76. Address: 45
    77. Failed Response. Code 2
    78. Address: 46
    79. Failed Response. Code 2
    80. Address: 47
    81. Failed Response. Code 2
    82. Address: 48
    83. Failed Response. Code 2
    84. Address: 49
    85. Failed Response. Code 2
    86. Address: 50
    87. Failed Response. Code 2
    88. Address: 51
    89. Failed Response. Code 2
    90. Address: 52
    91. Failed Response. Code 2
    92. Address: 53
    93. Failed Response. Code 2
    94. Address: 54
    95. Failed Response. Code 2
    96. Address: 55
    97. Failed Response. Code 2
    98. Address: 56
    99. Failed Response. Code 2
    100. Address: 57
    101. Failed Response. Code 2
    102. Address: 58
    103. Failed Response. Code 2
    104. Address: 59
    105. Failed Response. Code 2
    106. Address: 60
    107. Failed Response. Code 2
    108. Address: 61
    109. Failed Response. Code 2
    110. Address: 62
    111. Failed Response. Code 2
    112. Address: 63
    113. Failed Response. Code 2
    114. Address: 64
    115. Failed Response. Code 2
    116. Address: 65
    117. Failed Response. Code 2
    118. Address: 66
    119. Failed Response. Code 2
    120. Address: 67
    121. Failed Response. Code 2
    122. Address: 68
    123. Failed Response. Code 2
    124. Address: 69
    125. Failed Response. Code 2
    126. Address: 70
    127. Failed Response. Code 2
    128. Address: 71
    129. Failed Response. Code 2
    130. Address: 72
    131. Failed Response. Code 2
    132. Address: 73
    133. Failed Response. Code 2
    134. Address: 74
    135. Failed Response. Code 2
    136. Address: 75
    137. Failed Response. Code 2
    138. Address: 76
    139. Failed Response. Code 2
    140. Address: 77
    141. Failed Response. Code 2
    142. Address: 78
    143. Failed Response. Code 2
    144. Address: 79
    145. Failed Response. Code 2
    146. Address: 80
    147. Failed Response. Code 2
    148. Address: 81
    149. Failed Response. Code 2
    150. Address: 82
    151. Failed Response. Code 2
    152. Address: 83
    153. Failed Response. Code 2
    154. Address: 84
    155. Failed Response. Code 2
    156. Address: 85
    157. Failed Response. Code 2
    158. Address: 86
    159. Failed Response. Code 2
    160. Address: 87
    161. Failed Response. Code 2
    162. Address: 88
    163. Failed Response. Code 2
    164. Address: 89
    165. Failed Response. Code 2
    166. Address: 90
    167. Failed Response. Code 2
    168. Address: 91
    169. Failed Response. Code 2
    170. Address: 92
    171. Failed Response. Code 2
    172. Address: 93
    173. Failed Response. Code 2
    174. Address: 94
    175. Failed Response. Code 2
    176. Address: 95
    177. Failed Response. Code 2
    178. Address: 96
    179. Failed Response. Code 2
    180. Address: 97
    181. Failed Response. Code 2
    182. Address: 98
    183. Failed Response. Code 2
    184. Address: 99
    185. Failed Response. Code 2
    186. Address: 100
    187. Failed Response. Code 2
    188. Address: 101
    189. Failed Response. Code 2
    190. Address: 102
    191. Failed Response. Code 2
    192. Address: 103
    193. Failed Response. Code 2
    194. Address: 104
    195. Failed Response. Code 2
    196. Address: 105
    197. Failed Response. Code 2
    198. Address: 106
    199. Failed Response. Code 2
    200. Address: 107
    201. Failed Response. Code 2
    202. Address: 108
    203. Failed Response. Code 2
    204. Address: 109
    205. Failed Response. Code 2
    206. Address: 110
    207. Failed Response. Code 2
    208. Address: 111
    209. Failed Response. Code 2
    210. Address: 112
    211. Failed Response. Code 2
    212. Address: 113
    213. Failed Response. Code 2
    214. Address: 114
    215. Failed Response. Code 2
    216. Address: 115
    217. Failed Response. Code 2
    218. Address: 116
    219. Failed Response. Code 2
    220. Address: 117
    221. Failed Response. Code 2
    222. Address: 118
    223. Failed Response. Code 2
    224. Address: 119
    225. Failed Response. Code 2
    226. Address: 120
    227. Failed Response. Code 2
    228. Address: 121
    229. Failed Response. Code 2
    230. Address: 122
    231. Failed Response. Code 2
    232. Address: 123
    233. Failed Response. Code 2
    234. Address: 124
    235. Failed Response. Code 2
    236. Address: 125
    237. Failed Response. Code 2
    238. Address: 126
    239. Failed Response. Code 2
    240. Address: 127
    241. Failed Response. Code 2
    242. Done.
    243. Found 0 device(s).
    244.  
    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: Apr 14, 2019
  2. be80be

    AAC Fanatic!

    Jul 5, 2008
    1,768
    347
    Its dum. Why are you scaning it for address
    It has only one its listed in the datasheet 0x36
    Thats the slave address.
     
  3. Adam Tekle

    Thread Starter New Member

    Apr 14, 2019
    2
    0
    I tried that too. That was to just to check
    Code: This moves header to status register, and then tries to read it
    Code (Text):
    1. #include <Wire.h>
    2.   byte deviceAddressReading = 01101101;
    3.   byte deviceAddressWriting = 0110110;
    4.   byte statusRegisterAddress = 00001011;
    5. // the setup function runs once when you press reset or power the board
    6. void setup() {
    7. //  Wire.begin();
    8.   delay(1500);
    9.   Wire.begin();
    10. //  I2c.setSpeed(0);
    11. // I2c.pullup(1);
    12. //  I2c.timeOut(3000);
    13.   Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
    14.   while(!(Serial.available() > 0)) { }
    15.  
    16.   Serial.println("5s till communication with sensor");
    17.   delay(1000);
    18.   Serial.println("4s till communication with sensor");
    19.   delay(1000);
    20.   Serial.println("3s till communication with sensor");
    21.   delay(1000);
    22.   Serial.println("2s till communication with sensor");
    23.   delay(1000);
    24.   Serial.println("1s till communication with sensor");
    25.   delay(1000);
    26.   Serial.println("Communicating. Err Code For Head: ");
    27.   Wire.beginTransmission(108);
    28.   Wire.write(statusRegisterAddress);
    29.   Serial.println(String(Wire.endTransmission()));
    30.   Serial.println(String(Wire.requestFrom(109,1,true)));
    31.   Serial.println(String(Wire.read()));
    32.  
    33.  
    34. }

    This is what I get:
    Code (Text):
    1. 5s till communication with sensor
    2. 4s till communication with sensor
    3. 3s till communication with sensor
    4. 2s till communication with sensor
    5. 1s till communication with sensor
    6. Communicating. Err Code For Head:
    7. 2
    8. 0
    9. -1
    10.  
     
  4. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    7,578
    1,838
    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.
     
  5. be80be

    AAC Fanatic!

    Jul 5, 2008
    1,768
    347
    I think I'd try this
    Code (Text):
    1. #include <Arduino.h>
    2. #include <AS5601.h>
    3.  
    4.  
    5. AS5601 Sensor;
    6.  
    7.  
    8. void setup()
    9. {
    10.     delay( 1000 );
    11.     Serial.begin( 115200 );
    12.     Serial.println( F("Angle Measurement with AS5601") );
    13. }
    14.  
    15.  
    16. void loop()
    17. {
    18.     Serial.print( F("Magnitude: ") );
    19.     Serial.print( Sensor.getMagnitude() );
    20.  
    21.     Serial.print( F(" | Raw angle: ") );
    22.     Serial.print( Sensor.getRawAngle() );
    23.  
    24.     Serial.print( F(" | Clean angle: ") );
    25.     Serial.print( Sensor.getAngle() );
    26.  
    27.     if ( Serial.read() == '0' )
    28.     {
    29.         Sensor.setZeroPosition();
    30.         Serial.print( F(" | Zero position set!") );
    31.     }
    32.  
    33.     Serial.println();
    34.  
    35.     delay( 50 );
    36. }
    37.  
    You can down load the AS5601 Library for Arduino here https://github.com/bitfasching/AS5601
    Here the header
    Code (Text):
    1. /**
    2. * AS5601 Driver
    3. *
    4. * Arduino Library
    5. * for AS5601 Magnet Rotary Sensor
    6. *
    7. * License: BSD 3-Clause
    8. *
    9. * Nick Schwarzenberg,
    10. * 06/2016, v0.1.0
    11. */
    12.  
    13.  
    14. // include these dependencies in your top-level .ino!
    15. #include <Arduino.h>
    16. #include <Wire.h>
    17.  
    18. // prevent redefinitions
    19. #ifndef AS5601_driver
    20. #define AS5601_driver
    21.  
    22.  
    23. class AS5601
    24. {
    25.     public:
    26.  
    27.         /* :: Configuration :: */
    28.  
    29.  
    30.         // 7-bit device address
    31.         unsigned char address = 0x36;
    32.  
    33.         // 8-bit register addresses
    34.         static struct ByteRegister {
    35.             static const unsigned char
    36.             ZMCO = 0x00,
    37.             ABN = 0x09,
    38.             PUSHTHR = 0x0A,
    39.             STATUS = 0x0B,
    40.             AGC = 0x1A,
    41.             BURN = 0xFF;
    42.         } ByteRegister;
    43.  
    44.         // 16-bit register start (high byte) addresses
    45.         static struct WordRegister {
    46.             static const unsigned char
    47.             ZPOS = 0x01,
    48.             CONF = 0x03,
    49.             RAWANGLE = 0x0C,
    50.             ANGLE = 0x0E,
    51.             MAGNITUDE = 0x1B;
    52.         } WordRegister;
    53.  
    54.         // initialization
    55.         AS5601()
    56.         {
    57.             // host I2C bus as master in the default I2C channel
    58.             wireChannel = &Wire;
    59.             wireChannel->begin();
    60.         }
    61.  
    62.         // initialization with explicit I2C channel
    63.         AS5601(TwoWire *i2cChannel)
    64.         {
    65.             // host I2C bus as master in the passed channel
    66.             wireChannel = i2cChannel;
    67.             wireChannel->begin();
    68.         }
    69.  
    70.  
    71.         /* :: Low-Level Access :: */
    72.  
    73.  
    74.         // low-level: read one byte from an 8-bit register
    75.         unsigned char readRaw8( unsigned char registerAddress )
    76.         {
    77.             // send START for I2C frame to the AS5601
    78.             wireChannel->beginTransmission( this->address );
    79.  
    80.             // send register address
    81.             wireChannel->write( registerAddress );
    82.  
    83.             // flush, but do not release bus (no STOP)
    84.             wireChannel->endTransmission( false );
    85.  
    86.             // request one byte as response from the AS5601, release and wait
    87.             // (casting is necessary due to similar declarations of .requestFrom)
    88.             wireChannel->requestFrom( (uint8_t) this->address, (uint8_t) 1, (uint8_t) true );
    89.  
    90.             // return response
    91.             return wireChannel->read();
    92.         }
    93.  
    94.         // low-level: read two bytes as 16-bit word from two 8-bit registers
    95.         unsigned int readRaw16( unsigned char registerStartAddress )
    96.         {
    97.             // get high byte, then low byte
    98.             unsigned char highByte = this->readRaw8( registerStartAddress );
    99.             unsigned char lowByte = this->readRaw8( registerStartAddress + 1 );
    100.  
    101.             // combine to 16-bit word
    102.             return word( highByte, lowByte );
    103.         }
    104.  
    105.  
    106.         // low-level: write one byte to an 8-bit register
    107.         void writeRaw8( unsigned char registerAddress, unsigned char value )
    108.         {
    109.             // send START for I2C frame to the AS5601
    110.             wireChannel->beginTransmission( this->address );
    111.  
    112.             // send register address and value
    113.             wireChannel->write( registerAddress );
    114.             wireChannel->write( value );
    115.  
    116.             // flush and release (STOP)
    117.             wireChannel->endTransmission( true );
    118.         }
    119.  
    120.         // low-level: write 16-bit word as two bytes to two 8-bit registers
    121.         void writeRaw16( unsigned char registerStartAddress, unsigned int value )
    122.         {
    123.             // send high byte, then low byte
    124.             this->writeRaw8( registerStartAddress, (unsigned char) highByte( value ) );
    125.             this->writeRaw8( registerStartAddress + 1, (unsigned char) lowByte( value ) );
    126.         }
    127.  
    128.  
    129.  
    130.         /* :: Higher-Level Methods :: */
    131.  
    132.  
    133.         // query status to find out if magnet is detected
    134.         bool magnetDetected()
    135.         {
    136.             // query status register
    137.             unsigned char status = this->readRaw8( AS5601::ByteRegister::STATUS );
    138.  
    139.             // return true if bit 5 is set
    140.             return bitRead( status, 5 ) == 1 ? true : false;
    141.         }
    142.  
    143.         // get current magnetic magnitude (12 bit)
    144.         unsigned int getMagnitude()
    145.         {
    146.             // read and return two-byte magnitude
    147.             return this->readRaw16( AS5601::WordRegister::MAGNITUDE );
    148.         }
    149.  
    150.         // get current gain of AGC (8 bit)
    151.         unsigned char getGain()
    152.         {
    153.             // read and return one-byte gain
    154.             return this->readRaw8( AS5601::ByteRegister::AGC );
    155.         }
    156.  
    157.         // get raw angle (12 bit)
    158.         unsigned int getRawAngle()
    159.         {
    160.             // read and return two-byte raw angle
    161.             return this->readRaw16( AS5601::WordRegister::RAWANGLE );
    162.         }
    163.  
    164.         // set zero-position to specified raw angle (12 bit)
    165.         void setZeroPosition( unsigned int rawAngle )
    166.         {
    167.             // send position setting command
    168.             this->writeRaw16( AS5601::WordRegister::ZPOS, rawAngle );
    169.         }
    170.  
    171.         // convenience method: read current raw angle and pass it to .setZeroPosition(rawAngle)
    172.         void setZeroPosition() { this->setZeroPosition( this->getRawAngle() ); }
    173.  
    174.         // set angle resolution (affecting output value range and update speed)
    175.         void setResolution( unsigned int angleSteps )
    176.         {
    177.             char power = -1;
    178.  
    179.             // coerce angle steps to supported values (8, 16, 32, …, 2048)
    180.             angleSteps = min( max( angleSteps, 8 ), 2048 );
    181.  
    182.             // find dual logarithm (2^power >= angleSteps)
    183.             // (by comparing increasing powers of two with angleSteps)
    184.             while ( ( 1 << ++power ) < angleSteps );
    185.  
    186.             // send ABN setting command (-3 (2^3 = 8) shifts the powers 3…11 (for 8…2048) to 0…8)
    187.             this->writeRaw8( AS5601::ByteRegister::ABN, power-3 );
    188.         }
    189.  
    190.         // get zero-adjusted and filtered angle (12 bit)
    191.         unsigned int getAngle()
    192.         {
    193.             // read and return two-byte clean angle
    194.             return this->readRaw16( AS5601::WordRegister::ANGLE );
    195.         }
    196.  
    197.     private:
    198.  
    199.         TwoWire *wireChannel;
    200. };
    201.  
     
Loading...