Oled on serial, and Sensor on I2C,

Hi, heres the problem:
I have a oled µlcd144 on serial with its rx wire connected to the tx pin on the arduino, that is working. It uses a library, that uses the Arduino.h.

Then I have a HMC5883L over I2C SDA, SCL, that showes up on the I2C scanner with its address.

When I add code to write to the OLED, after Wire.I2C_TX(regbdata);
Wire.endTransmission();
to acess the I2C, the display doesnt write.
Heres the entire code:

#include <uLCD_144.h> // This library is locateded in Arduino\Libraries
#include <Wire.h>

uLCD_144 *myLCD; //Declaration of a pointer  [int *P;] class uLCD_144 is defined in uLCD_144.
                              //The above created pointer *myLCD is pointing to the class in the header.
                 
                 
 //-----------  HMC588-------------------------                
  

#define I2C_TX write
#define I2C_RX read

#define HMC5883_WriteAddress 0x1E //  i.e 0x3C >> 1    0x1e is the I2C Address of HMC5883L
#define HMC5883_ModeRegisterAddress 0x02
#define HMC5883_ContinuousModeCommand (uint8_t)0x00     // cast to uint8_t added to get code to compile under Arduino v1.0
#define HMC5883_DataOutputXMSBAddress 0x03

int regb = 0x01;
int regbdata = 0x40;
int outputData[6];               
                 
 //-------------------------------------
                 
                 
void setup() {

 *myLCD = uLCD_144(9600); // max is 100kbps and is dependent on the noise levels in the charger

 myLCD->setBgColor(0, 0, 0); // black
 myLCD->setContrast(0x0f);
 myLCD->setOpacity(0x00); // Text is: 0x00 transperent, 0x01 blocked

 myLCD->clrScreen();

 myLCD->setPenSize(0x00); //0x01 wire shape, 0x00 solide for all following graphic, except Polygon

                          //    x   y   r    rd    gn    bl
 myLCD->drawCircle(64, 64, 50, 0x3F,  0,   0); // max value: 0x3F ... 63 decimal
 //myLCD->drawCircle(64, 64, 45, 0x3f,  0x3f,  0x3f); // white
 myLCD->drawCircle(64, 64, 45, 0x00,  0x00,  0x00); //black
 delay(1000);
 myLCD->clrScreen();
 myLCD->setPenSize(0x01); //0x01 wire shape, 0x00 solide for all following graphic, except Polygon
 //column, row, font, rd,    gn,     bl,      string
 //myLCD->printStr( 0,    5,   2,   0x00,   0x3f,  0x00, "    DALDOSCH " ); // row 5 is middle
 //myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10, "    v.1.0");        // font: 0 5x7, 1 8x8, 2 8x12
 delay(500);
 // Draw Circle
 myLCD->drawCircle(64, 64, 50, 0x3F,  0,  0);
 delay(500);
 //                 x1   y1    x2    y2     color
 //myLCD->drawRect( 70,  20,   90,   30,   0,  0,  0);
 //delay(500);
 myLCD->drawLine( 2,  120,  120,  120,  0,  0,  0x3f);
 delay(500);
 // myLCD->drawPixel( 64, 32,  0x22,  0x00,  0x1f);
 //delay(1000);
 // myLCDDrawpolygon(
}

void loop() {
  int x,y,z;
  int angle;
  int i = 0;
  int a = 12;
  char str[100];
  
  /* 
  myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10,  " What the" );
  delay(500);
  myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10, a  );
  delay(500);
  */
  //-------------- This code here writes ----------------
  /*
   for(i=1; i<=100; i++)
   {
     sprintf(str, "Heat, T=%dC°", (int)i);             // create a sting in buffer str[]
     myLCD->printStr(0, 5, 2, 0x00,  0x3f, 0x00, str); // write to display  
     delay(0);
     myLCD->setPenSize(0x00); //Make following rectangle solid
     myLCD->drawRect( 64,  60,   88,   70,   0, 0, 0); // fill just the numbers with black
     delay(0);
    // myLCD->clrScreen();      
    if (i==99) i=0;
   }  
   */
  //------------------------------
 
 Wire.I2C_TX(regbdata); 
 
 Wire.endTransmission();
 
//---------------- this code here doesn`t write to the LCD ---------------
 
 myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10,  " What the" );

 delay(500);

//--------------------------------------------------------------------------

 Wire.beginTransmission(HMC5883_WriteAddress); //Initiate a transmission with HMC5883
 Wire.I2C_TX(HMC5883_ModeRegisterAddress);     //Place the Mode Register Address in send-buffer.
 Wire.I2C_TX(HMC5883_ContinuousModeCommand); //Place the command for Continuous op
 Wire.endTransmission();                                     //Send the send-buffer to HMC5883 and end the I2C 
 delay(100);

 Wire.beginTransmission(HMC5883_WriteAddress);  //Initiate a transmission with HMC5883 
 Wire.requestFrom(HMC5883_WriteAddress,6);      //Request 6 bytes of data from the address specified.

 delay(500);
 myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10, "    XXXX");
 delay(500);

 //Read the value of magnetic components X,Y and Z

 if(Wire.available() <= 6) // If the number of bytes available for reading is <=6
 {
   for(int i=0;i<6;i++)
   {
     outputData[i]=Wire.I2C_RX();  //Store the data in outputData buffer
   }
 }

 x=outputData[0] << 8 | outputData[1];  //Combine MSB and LSB of X Data output register
 z=outputData[2] << 8 | outputData[3];  //Combine MSB and LSB of Z Data output register
 y=outputData[4] << 8 | outputData[5];  //Combine MSB and LSB of Y Data output register
 angle = (double)atan2(y, x); // angle in radians
 
 angle += declinationAngle;
 
 // Correct for when signs are reversed.
 if (angle < 0)    angle += 2*PI;
   
 // Check for wrap due to addition of declination.
 if (angle > 2*PI) angle -= 2*PI;
  
 // Convert radians to degrees for readability.
 float bearing = angle * 180/PI; 
 
 //Serial.println();
 //Serial.println("Heading (degrees): " + String(bearing));
 
//Print the angle on the LCD Screen
//  Serial.write(254);
// Serial.write(128); //Goto line 1
// lcd.print("Angle=" + String(angle,2));
 
 
 
 //  Wire.beginTransmission(HMC5883_WriteAddress);
 //Wire.I2C_TX(regb);
 //Wire.I2C_TX(regbdata); 
  
//myLCD->printStr( 0,    10,   1,   0x10,   0x3f,  0x10, "    XXXX");

 delay(500);

 
 //----------------------------------
 
 uLCD_144 *myLCD;
 *myLCD = uLCD_144(9600);
 
  for(i=1; i<=100; i++)
   {
     sprintf(str, "Heat, T=%dC°", (int)i);             // create a sting in buffer str[]
     myLCD->printStr(0, 5, 2, 0x00,  0x3f, 0x00, str); // write to display  
     delay(0);
     myLCD->setPenSize(0x00); //Make following rectangle solid
     myLCD->drawRect( 64,  60,   88,   70,   0, 0, 0); // fill just the numbers with black
     delay(0);
    // myLCD->clrScreen();
    if (i==99) i=0;
   }  
   
}

I `d certainly appreciate any help,
thanks John

After 34 posts you should know to ue code tags when posting code :wink: Please edit your post.

And which board do you use? Wire.I2C_TX() isn't the normal method name. Wire.write() is the normal name. Also, don't forget to actually do a Wire.endTransmission().

Hi,
The definitions in the beginning of the code make it:

             #define I2C_TX write
             #define I2C_RX read
             #define HMC5883_WriteAddress 0x1E //  
             #define HMC5883_ModeRegisterAddress 0x02
             #define HMC5883_ContinuousModeCommand (uint8_t)0x00    
             #define HMC5883_DataOutputXMSBAddress 0x03

             int regb = 0x01;
             int regbdata = 0x40;
             int outputData[6];

wire.write(regbdata) -> wire.write(0x40)

Wire.endTransmission(); // Is also used.

I edited out all Wire. commands, including the Wire.endTransmission(), and only then would the lcd write.

Is it ok, that the lcd only needs one wire to work? Its Rx line must be removed when programming the Pro Mini, but when I leave it off it funktions anyway.

I thought that even though SCL, SDA and tx, rx both are serial, but totaly different libraries.

johnguy:
The definitions in the beginning of the code make it:

Why do such confusing macro stuff? (Actually applies for all macro stuff you do...)

johnguy:
Is it ok, that the lcd only needs one wire to work? Its Rx line must be removed when programming the Pro Mini, but when I leave it off it funktions anyway.

Depends on the screen and library. But it seems plausible a screen only needs to receive data (aka, has it's Rx connected).

johnguy:
I thought that even though SCL, SDA and tx, rx both are serial, but totaly different libraries.

Yeah, they are. They share nothing.

Only thing I notice is you do a Wire.write() without Wire.beginTransmission() or even Wire.begin()....

And why make a new local version of uLCD_144 *myLCD in loop?

 for(i=1; i<=100; i++)
   {
     //[...]
    if (i==99) i=0;
   }

Any why lock yourself in the for-loop?

if(Wire.available() <= 6) // If the number of bytes available for reading is <=6

Why explicitly read from Wire when you don't know the data is available?

Hi,
Is there a reason you are not using the HMC5883L library to read the sensor.

google hmc58831 arduino library

It comes with example code as well.

Tom... :slight_smile:

hi, instead of using

Wire.beginTransmission(HMC5883_WriteAddress)

I used Wire.begin();

And instead of using

wire.endTransmission();

I used

wire.end();
Now I`m getting something.

The for(;:wink: routine I only did to see, if I can write to the screen at all.

Thaks for looking at it!
John.

But just WHY it works with Wire.begin(); and Wire.end();

vs to

Wire.beginTransmission(HMC5883_WriteAddress, and Wire.endTransmission();

that didnt work.

I did Google,
but I`m happy that it works now.

Thanks,
John

TomGeorge:
Hi,
Is there a reason you are not using the HMC5883L library to read the sensor.

google hmc58831 arduino library

It comes with example code as well.

Tom... :slight_smile:

never sought of it, just copied a code that did compile. Something to go for next time. Just a beginner.
Thanks,
John

Not sure what you made of the code now. But in order to use I2C at all you need a Wire.begin() somewhere...