MCUdude / MiniCore

Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB
Other
979 stars 241 forks source link

Wire1 working incorrectly on 328PB #108

Closed K4ktus123 closed 5 years ago

K4ktus123 commented 5 years ago

I have a sketch that reads data from DS3231 RTC and prints it over serial. It works fine on first I2C port, but when I tried to connect it to second I2C it didn't work. Prints some garbage numbers over serial and freezes. Please let me know if you have any questions. Thanks!

MCUdude commented 5 years ago

Does the i2c_scanner sketch work on the 328PB when using Wire1.h?

K4ktus123 commented 5 years ago

No, it doesn't. Same thing as with my sketch - prints some garbage and freezes.

MCUdude commented 5 years ago

I suspect there's something wrong with your chip or something. Here's the output of the i2c_scanner when connected my DS3231 board (whick also has an on-board i2c eeprom) to TWI1.

Scanning...
I2C device found at address 0x57  !
I2C device found at address 0x68  !
done
/* I2C SCANNER
   http://playground.arduino.cc/Main/I2cScanner

   This sketch tests the standard 7-bit addresses
   Devices with higher bit address might not be seen properly.
 */

#include <Wire1.h>

void setup()
{
  Wire1.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire1.beginTransmission(address);
    error = Wire1.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}
K4ktus123 commented 5 years ago

This might be the case, although everything else seems to work fine. (SPI1 and UART1 not tested) I have a spare chip, but I don't have a second adapter board. I will get one on Monday or Thursday. If you come up anything else, please let me know. I'll post here as soon as get the second chip soldered and running. The weird part is that it behaves a little random, and now I got something like this: image

Maybe a wiring problem?

K4ktus123 commented 5 years ago

I quickly wrote this little sketch:

#include <Wire1.h>

void setup() {
  Serial.begin(9600);
  Wire1.begin();
}

void loop() {
  Wire1.beginTransmission(0x68);
  Wire1.write(0x01);
  Wire1.endTransmission();
  Wire1.requestFrom(0x68, 1);
  Serial.println(Wire1.read(), BIN);
  delay(1000);
}

And the output looks like this:

11111111111111111111111111111111
1001001
1001001
1001001
1001001
111111111111111111111111
1\1111111111111111
1001001
1\111111111111111111111111111111
1010000
111\111111111111111111111111111
1010000
1010000
1010000
1010000
1111
MCUdude commented 5 years ago

Mine output this:

110011
110011
110011
110011
110011
110011
110011
110011
110011
110011
110011
110011
110011
110011
110011

It may be a wiring problem because I'm not able to reproduce it in any way.

K4ktus123 commented 5 years ago

Just out of curiosity I tried it with internal oscillator, and surprisingly it works. So it must be some oscillator-related problem. How do you have the crystal connected on your board?

MCUdude commented 5 years ago

I am using a 16 MHz oscillator, but since the 328PB does not have a full swing oscillator driver, it's very touchy compared to other AVRs. If I touch the development board I've made for ut at the wrong places, it stops running. It's very sensitive to capacitive and resistive loads compared to 328P. For harsh environments, I'd rather use a dedicated clock to drive the 328PB just to prevent what you've experiencing.

K4ktus123 commented 5 years ago

Ok, I'll see what I can do with that. Maybe some dedicated driver? Is it possible to just feed the clock signal into one of the pins? I honestly think it was a bad move for Atmel/Microchip to remove the full swing oscillator. I've never had crystal-related problems with 328P.

MCUdude commented 5 years ago

Is it possible to just feed the clock signal into one of the pins?

Yes, it is. Just select some external oscillator option and burn bootloader. I've made a crystal driver for the ATtiny13, which does not come with a builtin crystal driver at all.

The schematics for it looks like this, where C1 and C2 = 10pF, R1 = 1M and R2 = 680R 450px-Pierce_Quarz_Oszillator svg

K4ktus123 commented 5 years ago

This is exactly what I needed! Just one more thing: does it matter which crystal pin I connect the signal to?

MCUdude commented 5 years ago

Just one more thing: does it matter which crystal pin I connect the signal to?

Yes, it does. You'll have to connect it to XTAL1

K4ktus123 commented 5 years ago

Alright, thank you so much!