Using MAXREFDES117 with Arduino Mega 2560

I got the Arduino codes for sensor MAXREFDES117 from Github: https://github.com/MaximIntegratedRefDesTeam/RD117_ARDUINO

Since I am using Arduino Mega 2560, I changed this part under SoftI2CMaster.h from this:

#ifdef ARDUINO_AVR_UNO
#define SDA_PORT PORTC
#define SDA_PIN 4
#define SCL_PORT PORTC
#define SCL_PIN 5
#endif

to

#ifdef ARDUINO_AVR_UNO
#define SDA_PORT PORTD
#define SDA_PIN 20
#define SCL_PORT PORTD
#define SCL_PIN 21
#endif

However, I got compelling error: 'SCL_PORT' was not declared in this scope.

Does anyone knows what is wrong?

I think you are still looking for an Arduino UNO

Try... #ifdef ARDUINO_AVR_MEGA2560

Thanks for replying. I changed it to #ifdef ARDUINO_AVR_MEGA2560.
Error message now is: Error compiling for board Arduino/Genuino Mega or Mega 2560.

Does it mean that this code cannot work for Arduino mega?

ShawnL_7157:
Thanks for replying. I changed it to #ifdef ARDUINO_AVR_MEGA2560.
Error message now is: Error compiling for board Arduino/Genuino Mega or Mega 2560.

Does it mean that this code cannot work for Arduino mega?

No, there is very little code, if any, that will run on an Uno but not on a Mega.

It means that you need to post your entire code and entire error message.

Here is the copied error message:

Arduino: 1.8.5 (Mac OS X), Board: “Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)”

In file included from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:78:0:
sketch/algorithm.h:66:0: warning: “true” redefined
#define true 1
^
In file included from /private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:24:0,
from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:77:
/private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include/stdbool.h:43:0: note: this is the location of the previous definition
#define true true
^
In file included from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:78:0:
sketch/algorithm.h:67:0: warning: “false” redefined
#define false 0
^
In file included from /private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:24:0,
from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:77:
/private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include/stdbool.h:42:0: note: this is the location of the previous definition
#define false false
^
In file included from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:78:0:
sketch/algorithm.h:71:0: warning: “min” redefined
#define min(x,y) ((x) < (y) ? (x) : (y))
^
In file included from /Users/ShawnLee/Downloads/RD117_ARDUINO_V01_00/Design Files/RD117_ARDUINO/RD117_ARDUINO.ino:77:0:
/private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:92:0: note: this is the location of the previous definition
#define min(a,b) ((a)<(b)?(a):(b))
^
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s: Assembler messages:
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:111: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:113: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:115: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:117: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:119: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:144: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:146: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1269: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1270: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1275: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1281: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1285: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1291: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1294: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1297: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1303: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1307: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1313: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1346: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1352: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1355: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1359: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1364: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1375: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1378: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1382: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1386: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1389: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1395: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1419: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1420: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1422: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1424: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1426: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1910: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1911: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1912: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1913: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1916: Error: number must be positive and less than 8
/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T//cc8ofd43.s:1918: Error: number must be positive and less than 8
lto-wrapper: /private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/tools/avr/bin/avr-gcc returned 1 exit status
/private/var/folders/y9/m4ds1nkn40l0gww128qg3w880000gn/T/AppTranslocation/546B948F-67F8-43E0-BFB1-B29B3D736641/d/Arduino-2.app/Contents/Java/hardware/tools/avr/bin/…/lib/gcc/avr/4.9.2/…/…/…/…/avr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

If you put all that inside a code block, it’ll be much easier for us to read and interpret. Please read the post (at the top of the listing) called How to use this forum - please read. It’s full of all sorts of guides to getting the best help here. Decyphering all your line breaks doesn’t look like much fun! ::()

Also, are you sure you have the Mega 2560 selected as the board in the IDE? All those references to your code show line numbers. Since your code is top secret, there is little we can do from here to help trace the source of the error.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

I used the exact code from GitHub - MaximIntegratedRefDesTeam/RD117_ARDUINO: MAXREFDES117 firmware for Arduino platforms and only made changes in SoftI2CMaster.h. The codes are too long. I will split it into a few posts. Below are the codes.

Part 1

#ifndef SOFTI2CMASTER_H_

#define SOFTI2DMASTER_H_

#include <avr/io.h>
#include <Arduino.h>

#if defined(ARDUINO_AVR_FLORA8) || defined(ARDUINO_AVR_LILYPAD_USB)
#define SDA_PORT PORTD
#define SDA_PIN 1
#define SCL_PORT PORTD
#define SCL_PIN 0
#endif

#ifdef ARDUINO_AVR_MEGA2560
#define SDA_PORT PORTD
#define SDA_PIN 20
#define SCL_PORT PORTD
#define SCL_PIN 21
#endif

#define I2C_TIMEOUT 100
#define I2C_NOINTERRUPT 0
#define I2C_SLOWMODE 1
#define FAC 1
#define I2C_CPUFREQ (F_CPU/FAC)

#ifndef _SOFTI2C_H
#define _SOFTI2C_H   1

// Init function. Needs to be called once in the beginning.
// Returns false if SDA or SCL are low, which probably means 
// a I2C bus lockup or that the lines are not pulled up.
boolean __attribute__ ((noinline)) i2c_init(void);

// Start transfer function: <addr> is the 8-bit I2C address (including the R/W
// bit). 
// Return: true if the slave replies with an "acknowledge", false otherwise
bool __attribute__ ((noinline)) i2c_start(uint8_t addr); 

// Similar to start function, but wait for an ACK! Be careful, this can 
// result in an infinite loop!
void  __attribute__ ((noinline)) i2c_start_wait(uint8_t addr);

// Repeated start function: After having claimed the bus with a start condition,
// you can address another or the same chip again without an intervening 
// stop condition.
// Return: true if the slave replies with an "acknowledge", false otherwise
bool __attribute__ ((noinline)) i2c_rep_start(uint8_t addr);

// Issue a stop condition, freeing the bus.
void __attribute__ ((noinline)) i2c_stop(void) asm("ass_i2c_stop");

// Write one byte to the slave chip that had been addressed
// by the previous start call. <value> is the byte to be sent.
// Return: true if the slave replies with an "acknowledge", false otherwise
bool __attribute__ ((noinline)) i2c_write(uint8_t value) asm("ass_i2c_write");
 
// Read one byte. If <last> is true, we send a NAK after having received 
// the byte in order to terminate the read sequence. 
uint8_t __attribute__ ((noinline)) i2c_read(bool last);

Part 2

// You can set I2C_CPUFREQ independently of F_CPU if you 
// change the CPU frequency on the fly. If you do not define it,
// it will use the value of F_CPU
#ifndef I2C_CPUFREQ
#define I2C_CPUFREQ F_CPU
#endif

// If I2C_FASTMODE is set to 1, then the highest possible frequency below 400kHz
// is selected. Be aware that not all slave chips may be able to deal with that!
#ifndef I2C_FASTMODE
#define I2C_FASTMODE 0
#endif

// If I2C_FASTMODE is not defined or defined to be 0, then you can set
// I2C_SLOWMODE to 1. In this case, the I2C frequency will not be higher 
// than 25KHz. This could be useful for problematic buses.
#ifndef I2C_SLOWMODE
#define I2C_SLOWMODE 0
#endif

// if I2C_NOINTERRUPT is 1, then the I2C routines are not interruptable.
// This is most probably only necessary if you are using a 1MHz system clock,
// you are communicating with a SMBus device, and you want to avoid timeouts.
// Be aware that the interrupt bit is enabled after each call. So the
// I2C functions should not be called in interrupt routines or critical regions.
#ifndef I2C_NOINTERRUPT
#define I2C_NOINTERRUPT 0
#endif

// I2C_TIMEOUT can be set to a value between 1 and 10000.
// If it is defined and nonzero, it leads to a timeout if the
// SCL is low longer than I2C_TIMEOUT milliseconds, i.e., max timeout is 10 sec
#ifndef I2C_TIMEOUT
#define I2C_TIMEOUT 0
#else 
#if I2C_TIMEOUT > 10000
#error I2C_TIMEOUT is too large
#endif
#endif

#define I2C_TIMEOUT_DELAY_LOOPS (I2C_CPUFREQ/1000UL)*I2C_TIMEOUT/4000UL
#if I2C_TIMEOUT_DELAY_LOOPS < 1
#define I2C_MAX_STRETCH 1
#else
#if I2C_TIMEOUT_DELAY_LOOPS > 60000UL
#define I2C_MAX_STRETCH 60000UL
#else
#define I2C_MAX_STRETCH I2C_TIMEOUT_DELAY_LOOPS
#endif
#endif

#if I2C_FASTMODE
#define I2C_DELAY_COUNTER (((I2C_CPUFREQ/400000L)/2-19)/3)
#else
#if I2C_SLOWMODE
#define I2C_DELAY_COUNTER (((I2C_CPUFREQ/25000L)/2-19)/3)
#else
#define I2C_DELAY_COUNTER (((I2C_CPUFREQ/100000L)/2-19)/3)
#endif
#endif

// Table of I2C bus speed in kbit/sec:
// CPU clock:           1MHz   2MHz    4MHz   8MHz   16MHz   20MHz
// Fast I2C mode          40     80     150    300     400     400
// Standard I2C mode      40     80     100    100     100     100
// Slow I2C mode          25     25      25     25      25      25     

// constants for reading & writing
#define I2C_READ    1
#define I2C_WRITE   0

// map the IO register back into the IO address space
#define SDA_DDR       (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR       (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT       _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT       _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)

#ifndef __tmp_reg__
#define __tmp_reg__ 0
#endif

Hi,
Did the original code work before you moded the library?

Tom... :slight_smile:

Part 3

// Internal delay functions.
void __attribute__ ((noinline)) i2c_delay_half(void) asm("ass_i2c_delay_half");
void __attribute__ ((noinline)) i2c_wait_scl_high(void) asm("ass_i2c_wait_scl_high");

void  i2c_delay_half(void)
{ // function call 3 cycles => 3C
#if I2C_DELAY_COUNTER < 1
  __asm__ __volatile__ (" ret");
  // 7 cycles for call and return
#else
  __asm__ __volatile__ 
    (
     " ldi      r25, %[DELAY]           ;load delay constant   ;; 4C nt"
     "_Lidelay: nt"
     " dec r25                          ;decrement counter     ;; 4C+xC nt"
     " brne _Lidelay                                           ;;5C+(x-1)2C+xCnt"
     " ret                                                     ;; 9C+(x-1)2C+xC = 7C+xC" 
     : : [DELAY] "M" I2C_DELAY_COUNTER : "r25");
  // 7 cycles + 3 times x cycles
#endif
}

void i2c_wait_scl_high(void)
{
#if I2C_TIMEOUT <= 0
  __asm__ __volatile__ 
    ("_Li2c_wait_stretch: nt"
     " sbis	%[SCLIN],%[SCLPIN]	;wait for SCL high nt" 
     " rjmp	_Li2c_wait_stretch nt"
     " cln                              ;signal: no timeout nt"
     " ret "
     : : [SCLIN] "I" (SCL_IN), [SCLPIN] "I" (SCL_PIN));
#else
  __asm__ __volatile__ 
    ( " ldi     r27, %[HISTRETCH]       ;load delay counter nt"
      " ldi     r26, %[LOSTRETCH] nt"
      "_Lwait_stretch: nt"
      " clr     __tmp_reg__             ;do next loop 255 times nt"
      "_Lwait_stretch_inner_loop: nt"
      " rcall   _Lcheck_scl_level       ;call check function   ;; 12C nt"
      " brpl    _Lstretch_done          ;done if N=0           ;; +1 = 13Cnt"
      " dec     __tmp_reg__             ;dec inner loop counter;; +1 = 14Cnt"
      " brne    _Lwait_stretch_inner_loop                      ;; +2 = 16Cnt"
      " sbiw    r26,1                   ;dec outer loop counter nt"
      " brne    _Lwait_stretch          ;continue with outer loop nt"
      " sen                             ;timeout -> set N-bit=1 nt"
      " rjmp _Lwait_return              ;and return with N=1nt"
      "_Lstretch_done:                  ;SCL=1 sensed nt"            
      " cln                             ;OK -> clear N-bit nt"
      " rjmp _Lwait_return              ; and return with N=0 nt"

      "_Lcheck_scl_level:                                      ;; call = 3Cnt"
      " cln                                                    ;; +1C = 4C nt"
      " sbic	%[SCLIN],%[SCLPIN]      ;skip if SCL still low ;; +2C = 6C nt"
      " rjmp    _Lscl_high                                     ;; +0C = 6C nt"
      " sen                                                    ;; +1 = 7Cnt "
      "_Lscl_high: "
      " nop                                                    ;; +1C = 8C nt"
      " ret                             ;return N-Bit=1 if low ;; +4 = 12Cnt"

      "_Lwait_return:"
      : : [SCLIN] "I" (SCL_IN), [SCLPIN] "I" (SCL_PIN), 
	[HISTRETCH] "M" (I2C_MAX_STRETCH>>8), 
	[LOSTRETCH] "M" (I2C_MAX_STRETCH&0xFF)
      : "r26", "r27");
#endif
}


boolean i2c_init(void)
{
  __asm__ __volatile__ 
    (" cbi      %[SDADDR],%[SDAPIN]     ;release SDA nt" 
     " cbi      %[SCLDDR],%[SCLPIN]     ;release SCL nt" 
     " cbi      %[SDAOUT],%[SDAPIN]     ;clear SDA output value nt" 
     " cbi      %[SCLOUT],%[SCLPIN]     ;clear SCL output value nt" 
     " clr      r24                     ;set return value to false nt"
     " clr      r25                     ;set return value to false nt"
     " sbis     %[SDAIN],%[SDAPIN]      ;check for SDA highnt"
     " ret                              ;if low return with false nt"  
     " sbis     %[SCLIN],%[SCLPIN]      ;check for SCL high nt"
     " ret                              ;if low return with false nt" 
     " ldi      r24,1                   ;set return value to true nt"
     " ret "
     : :
       [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN), 
       [SCLIN] "I" (SCL_IN), [SCLOUT] "I" (SCL_OUT),
       [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN), 
       [SDAIN] "I" (SDA_IN), [SDAOUT] "I" (SDA_OUT)); 
  return true;
}

bool  i2c_start(uint8_t addr)
{
  __asm__ __volatile__ 
    (
#if I2C_NOINTERRUPT
     " cli                              ;clear IRQ bit nt"
#endif
     " sbis     %[SCLIN],%[SCLPIN]      ;check for clock stretching slavent"
     " rcall    ass_i2c_wait_scl_high   ;wait until SCL=Hnt" 
     " sbi      %[SDADDR],%[SDAPIN]     ;force SDA low  nt" 
     " rcall    ass_i2c_delay_half      ;wait T/2 nt"
     " rcall    ass_i2c_write           ;now write address nt"
     " ret"
     : : [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN),
       [SCLIN] "I" (SCL_IN),[SCLPIN] "I" (SCL_PIN)); 
  return true; // we never return here!
}

bool  i2c_rep_start(uint8_t addr)
{
  __asm__ __volatile__ 

    (
#if I2C_NOINTERRUPT
     " cli nt"
#endif
     " sbi	%[SCLDDR],%[SCLPIN]	;force SCL low nt" 
     " rcall 	ass_i2c_delay_half	;delay  T/2 nt" 
     " cbi	%[SDADDR],%[SDAPIN]	;release SDA nt" 
     " rcall	ass_i2c_delay_half	;delay T/2 nt" 
     " cbi	%[SCLDDR],%[SCLPIN]	;release SCL nt" 
     " rcall 	ass_i2c_delay_half	;delay  T/2 nt" 
     " sbis     %[SCLIN],%[SCLPIN]      ;check for clock stretching slavent"
     " rcall    ass_i2c_wait_scl_high   ;wait until SCL=Hnt" 
     " sbi 	%[SDADDR],%[SDAPIN]	;force SDA low nt" 
     " rcall 	ass_i2c_delay_half	;delay	T/2 nt" 
     " rcall    ass_i2c_write       nt"
     " ret"
     : : [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN),[SCLIN] "I" (SCL_IN),
         [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN)); 
  return true; // just to fool the compiler
}

void  i2c_start_wait(uint8_t addr)
{
 __asm__ __volatile__ 
   (
    " push	r24                     ;save original parameter nt"
    "_Li2c_start_wait1: nt"
    " pop       r24                     ;restore original parameternt"
    " push      r24                     ;and save again nt"
#if I2C_NOINTERRUPT
    " cli                               ;disable interrupts nt"
#endif
    " sbis     %[SCLIN],%[SCLPIN]      ;check for clock stretching slavent"
    " rcall    ass_i2c_wait_scl_high   ;wait until SCL=Hnt" 
    " sbi 	%[SDADDR],%[SDAPIN]	;force SDA low nt" 
    " rcall 	ass_i2c_delay_half	;delay T/2 nt" 
    " rcall 	ass_i2c_write	        ;write address nt" 
    " tst	r24		        ;if device not busy -> done nt" 
    " brne	_Li2c_start_wait_done nt" 
    " rcall	ass_i2c_stop	        ;terminate write & enable IRQ nt" 
    " rjmp	_Li2c_start_wait1	;device busy, poll ack again nt" 
    "_Li2c_start_wait_done: nt"
    " pop       __tmp_reg__             ;pop off orig argument nt"
    " ret "
    : : [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN),
      [SCLIN] "I" (SCL_IN),[SCLPIN] "I" (SCL_PIN)); 
}

Part 4

void  i2c_stop(void)
{
  __asm__ __volatile__ 
    (
     " sbi      %[SCLDDR],%[SCLPIN]     ;force SCL low nt" 
     " sbi      %[SDADDR],%[SDAPIN]     ;force SDA low nt" 
     " rcall    ass_i2c_delay_half      ;T/2 delay nt"
     " cbi      %[SCLDDR],%[SCLPIN]     ;release SCL nt" 
     " rcall    ass_i2c_delay_half      ;T/2 delay nt"
     " sbis     %[SCLIN],%[SCLPIN]      ;check for clock stretching slavent"
     " rcall    ass_i2c_wait_scl_high   ;wait until SCL=Hnt" 
     " cbi      %[SDADDR],%[SDAPIN]     ;release SDA nt" 
     " rcall    ass_i2c_delay_half nt"
#if I2C_NOINTERRUPT
     " sei                              ;enable interrupts again!nt"
#endif
     : : [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
         [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN)); 
}

bool i2c_write(uint8_t value)
{
  __asm__ __volatile__ 
    (
     " sec                              ;set carry flag nt"
     " rol      r24                     ;shift in carry and shift out MSB nt"
     " rjmp _Li2c_write_first nt"
     "_Li2c_write_bit:nt"
     " lsl      r24                     ;left shift into carry ;; 1Cnt"
     "_Li2c_write_first:nt"
     " breq     _Li2c_get_ack           ;jump if TXreg is empty;; +1 = 2C nt"
     " sbi      %[SCLDDR],%[SCLPIN]     ;force SCL low         ;; +2 = 4C nt"
     " nop nt"
     " nop nt"
     " nop nt"
     " brcc     _Li2c_write_low                                ;;+1/+2=5/6Cnt"
     " nop                                                     ;; +1 = 7C nt"
     " cbi %[SDADDR],%[SDAPIN]        ;release SDA           ;; +2 = 9C nt"
     " rjmp      _Li2c_write_high                              ;; +2 = 11C nt"
     "_Li2c_write_low: nt"
     " sbi %[SDADDR],%[SDAPIN] ;force SDA low         ;; +2 = 9C nt"
     " rjmp _Li2c_write_high                               ;;+2 = 11C nt"
     "_Li2c_write_high: nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;;+X = 11C+Xnt"
#endif
     " cbi %[SCLDDR],%[SCLPIN] ;release SCL           ;;+2 = 13C+Xnt"
     " cln                              ;clear N-bit           ;;+1 = 14C+Xnt"
     " nop nt"
     " nop nt"
     " nop nt"
     " sbis %[SCLIN],%[SCLPIN] ;check for SCL high    ;;+2 = 16C+Xnt"
     " rcall    ass_i2c_wait_scl_high nt"
     " brpl     _Ldelay_scl_high                              ;;+2 = 18C+Xnt"
     "_Li2c_write_return_false: nt"
     " clr      r24                     ; return false because of timeout nt"
     " rjmp     _Li2c_write_return nt"
     "_Ldelay_scl_high: nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;;+X= 18C+2Xnt"
#endif
     " rjmp _Li2c_write_bit nt"
     "              ;; +2 = 20C +2X for one bit-loop nt"
     "_Li2c_get_ack: nt"
     " sbi %[SCLDDR],%[SCLPIN] ;force SCL low ;; +2 = 5C nt"
     " nop nt"
     " nop nt"
     " cbi %[SDADDR],%[SDAPIN] ;release SDA ;;+2 = 7C nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2 ;; +X = 7C+X nt"
#endif
     " clr r25                                            ;; 17C+2X nt"
     " clr r24        ;return 0              ;; 14C + X nt"
     " cbi %[SCLDDR],%[SCLPIN] ;release SCL ;; +2 = 9C+Xnt"
     "_Li2c_ack_wait: nt"
     " cln                              ; clear N-bit          ;; 10C + Xnt" 
     " nop nt"
     " sbis %[SCLIN],%[SCLPIN] ;wait SCL high         ;; 12C + X nt"
     " rcall    ass_i2c_wait_scl_high nt"
     " brmi     _Li2c_write_return_false                       ;; 13C + X nt "
     " sbis %[SDAIN],%[SDAPIN]      ;if SDA hi -> return 0 ;; 15C + X nt"
     " ldi r24,1                   ;return true           ;; 16C + X nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;; 16C + 2X nt"
#endif
     "_Li2c_write_return: nt"
     " nop nt "
     " nop nt "
     " sbi %[SCLDDR],%[SCLPIN] ;force SCL low so SCL=H is shortnt"
     " ret nt"
     "              ;; + 4 = 17C + 2X for acknowldge bit"
     ::
      [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
      [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN), [SDAIN] "I" (SDA_IN)); 
  return true; // fooling the compiler
}

uint8_t i2c_read(bool last)
{
  __asm__ __volatile__ 
    (
     " ldi r23,0x01 nt"
     "_Li2c_read_bit: nt"
     " sbi %[SCLDDR],%[SCLPIN] ;force SCL low         ;; 2C nt" 
     " cbi %[SDADDR],%[SDAPIN] ;release SDA(prev. ACK);; 4C nt" 
     " nop nt"
     " nop nt"
     " nop nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;; 4C+X nt" 
#endif
     " cbi %[SCLDDR],%[SCLPIN] ;release SCL           ;; 6C + X nt" 
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;; 6C + 2X nt" 
#endif
     " cln                              ; clear N-bit          ;; 7C + 2X nt"
     " nop nt "
     " nop nt "
     " nop nt "
     " sbis     %[SCLIN], %[SCLPIN]     ;check for SCL high    ;; 9C +2X nt" 
     " rcall    ass_i2c_wait_scl_high nt"
     " brmi     _Li2c_read_return       ;return if timeout     ;; 10C + 2Xnt"
     " clc          ;clear carry flag      ;; 11C + 2Xnt" 
     " sbic %[SDAIN],%[SDAPIN] ;if SDA is high        ;; 11C + 2Xnt" 
     " sec        ;set carry flag        ;; 12C + 2Xnt" 
     " rol r23        ;store bit             ;; 13C + 2Xnt" 
     " brcc _Li2c_read_bit        ;while receiv reg not full nt"
     "                         ;; 15C + 2X for one bit loop nt" 
     
     "_Li2c_put_ack: nt" 
     " sbi %[SCLDDR],%[SCLPIN] ;force SCL low         ;; 2C nt" 
     " cpi r24,0                                          ;; 3C nt" 
     " breq _Li2c_put_ack_low ;if (ack=0) ;; 5C nt" 
     " cbi %[SDADDR],%[SDAPIN] ;release SDA nt" 
     " rjmp _Li2c_put_ack_high nt" 
     "_Li2c_put_ack_low:                ;else nt" 
     " sbi %[SDADDR],%[SDAPIN] ;force SDA low         ;; 7C nt" 
     "_Li2c_put_ack_high: nt" 
     " nop nt "
     " nop nt "
     " nop nt "
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;; 7C + X nt" 
#endif
     " cbi %[SCLDDR],%[SCLPIN] ;release SCL           ;; 9C +X nt" 
     " cln                              ;clear N               ;; +1 = 10Cnt"
     " nop nt "
     " nop nt "
     " sbis %[SCLIN],%[SCLPIN] ;wait SCL high         ;; 12C + Xnt" 
     " rcall    ass_i2c_wait_scl_high nt"
#if I2C_DELAY_COUNTER >= 1
     " rcall ass_i2c_delay_half ;delay T/2             ;; 11C + 2Xnt" 
#endif
     "_Li2c_read_return: nt"
     " nop nt "
     " nop nt "
     "sbi %[SCLDDR],%[SCLPIN] ;force SCL low so SCL=H is shortnt"
     " mov r24,r23                                        ;; 12C + 2X nt"
     " clr r25                                            ;; 13 C + 2Xnt"
     " ret                                                     ;; 17C + X"
     ::
      [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
      [SDADDR] "I"  (SDA_DDR), [SDAPIN] "I" (SDA_PIN), [SDAIN] "I" (SDA_IN) 
     ); 
  return ' '; // fool the compiler!
}

#endif


#endif

No it didnt work even before i modify

ShawnL_7157:
No it didnt work even before i modify

Well show us the un-modified code, get it working first then, change it.
Tom... :slight_smile:

Like i mentioned in the prev posts, i only changed one small part of the entire SoftI2CMaster.h code. Which is from:

[Original code]

#ifdef ARDUINO_AVR_UNO
#define SDA_PORT PORTC
#define SDA_PIN 4
#define SCL_PORT PORTC
#define SCL_PIN 5
#endif

to

[Modified Code]

#ifdef ARDUINO_AVR_UNO
#define SDA_PORT PORTD
#define SDA_PIN 20
#define SCL_PORT PORTD
#define SCL_PIN 21
#endif

I did prototype MAXREFDES117# with Arduino Mega 2560, as well, and also ran into incurable problems myself. Thus, I got rid of SoftI2CMaster.h entirely and replaced all I2C calls by their equivalents from the standard Wire library. The whole project is described here: