Communicating via i2c with AXE033

Hey, I’ve just gotten my panda working, and I found an old AXE033 LED display laying about, I wanted to get the two working together, however the AXE033, being designed for PICAXE, only includes the data required to get it working with PICAXE, and doesn’t actually have a table with its registers. Would someone be able to please work out what registers I need to use according to this datasheet?

If possible, please post a little code snippet of how running a command might look, I’ve tried setting it up myself but keep on getting errors :).

This is my current attempt to do this, but I cannot work out how to convert a string to a byte or bytes, so that they can be sent to the display. Anyone got any ideas? Its giving me “An unhandled exception of type ‘System.Exception’ occurred in mscorlib.dll” at the line labled error here

            Thread.Sleep(2000);

            I2CDevice.Configuration con2 =
            new I2CDevice.Configuration(0x63, 100);
            I2CDevice AXE033 = new I2CDevice(con2);
            
            I2CDevice.I2CTransaction[] xActionsAXE033 =
            new I2CDevice.I2CTransaction[2];

            Thread.Sleep(500);

            byte[] RegisterValueAXE1 = new byte[3] { 254,128,255 };
            xActionsAXE033[0] = I2CDevice.CreateWriteTransaction(RegisterValueAXE1);

            //Error Here
            String msg = "h";
            byte msgByte = Convert.ToByte(msg);



            byte[] RegisterValueAXE = new byte[2] { msgByte,255};
            xActionsAXE033[1] = I2CDevice.CreateWriteTransaction(RegisterValueAXE);

            AXE033.Execute(xActionsAXE033, 1000);

            Debug.Print("Done");

Here’s a code sample :

public void Write(int Address, string Text)
        {
            var Addr = Address;
            var xActions = new I2CDevice.I2CTransaction[1];
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes("00"+Text);  // the "00" string reserves the room for the 2 bytes address that follows
            buffer[0] = (byte)(Address >> 8);
            buffer[1] = (byte)(Address & 0xFF);
            xActions[0] = I2CDevice.CreateWriteTransaction(buffer);
            I2C.Execute(xActions, 1000);
        }

Taken from here : http://www.fezzer.com/project/167/i2c-eeprom/

Thanks Bec, Ill give that a try - I’ve also got a question up in the general forum, if you have a second could you please give it a glance?

cheers, Xarren

The precise BASIC command I am trying to replicate is

writei2c 0,(Hello!123,255)

So that should be register 0, then the message bytes, finished by a 255,
How would I add the 255 to the end of an array which I do not know the lengh of? Also, with the register address, do I have to send it in a seperate command, or can I send it in the same command as the same byte?

I am completely new to i2c just trying to figure it out (and c# in general)

Xarren. the ‘0’ is just the internal address, it seems to be alway’s 0
The external address is 0xC6 ( remember to shift this to 7 bit ie…0xC6 >> 1 = 0x63)

Just create a buffer as chris has shown you. However he has shown you a two byte address where as this device is only byte addressable ( same as the DS1307 RTC, example on fezzer )

Cheers Ian

Oh yes sorry terminate your text with 0xff. I don’t know how to append control chars with c#
I would probably get the length of the string… create the array and plant the control char into the last byte… But someone here will know

Thanks Ian, Ill try doing that :slight_smile:

Someone please stop me from killing myself. I’ve spent about 5 hours today trying to make this silly LCD work, and it is still defeating me. I know the screen itself works, when i short the test jumpers it displays the test message just fine, however whenever I try to send it any messages, nothing happens (And yes, the i2c jumper is shorted).

Please have a look at my code and try to work out how it is different from the BASIC code presented in the AXE033 datasheet. Btw, my SCL and SDA are soldered properly, as I am able to access the DS1307 which is on that same board and bus just fine.

Here is what it should be, in BASIC code:

init: pause 500 // wait for display to initialise
i2cslave $C6,i2cslow,i2cbyte // set up i2cslave for LCD
main: writei2c 0,(254,128,255) // move to start of first line
pause 10 // wait for LCD to process data
writei2c 0,("Hello!123",255) // output text
end

Here is my attempt to achieve this in C# :

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.IO;

namespace AXE033_API
{

    public class AXE033_LCD
    {
        private static I2CDevice.Configuration AXE033_Config;
        private static I2CDevice AXE033;

        public AXE033_LCD(byte Address, int ClockRateKHz)
        {
            AXE033_Config = new I2CDevice.Configuration(Address, ClockRateKHz);
            AXE033 = new I2CDevice(AXE033_Config);
        }

        public bool MoveCursor(int Line, int Position)
        {
            int MemoryPosition;
            byte[] Command;

            if (Line == 1) {
                MemoryPosition = 128;
            } else if (Line == 2) {
                MemoryPosition = 192;
            } else { 
                return false;
            }

            MemoryPosition += Position;

            Command = new byte[4] {0,254,(byte)MemoryPosition, 255};

            var xActions = new I2CDevice.I2CTransaction[2];
            byte[] reg = new byte[1] { 0 };
            xActions[0] = I2CDevice.CreateWriteTransaction(reg);
            xActions[1] = I2CDevice.CreateWriteTransaction(Command);
                
            AXE033.Execute(xActions, 1000);
                     
            Thread.Sleep(100);
            Debug.Print("Cursor Moved");
            return true;
        }

        public bool DisplayMessage(string Message) 
        {
            int MessageLength = Message.Length;

            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Message+"0");
            buffer[MessageLength] = 255;
            var xActions = new I2CDevice.I2CTransaction[2];
            byte[] reg = new byte[1] { 0 };
            xActions[0] = I2CDevice.CreateWriteTransaction(reg);
            xActions[1] = I2CDevice.CreateWriteTransaction(buffer);

            AXE033.Execute(xActions, 1000);

            Thread.Sleep(100);
            Debug.Print("Message Displayed");
            return true;    
        }
    
    }

    public class Program
    {

        public static void Main()
        {
            Thread.Sleep(2500);
            AXE033_LCD AXE033 = new AXE033_LCD(0x63, 100);
            AXE033.MoveCursor(1, 1);
            AXE033.DisplayMessage("Hello");

        }

    }
}

Can anyone spot what I’m doing wrong? Its probably something simple to do with me misunderstanding the way i2c works, and I have really tried for a long time to make this work, but it isn’t happening.

Xarren… I can’t help explicitly as I don’t have this board to hand… However it appears as if there are just two devices on this board… DS1307 and a LCD module, If this be the case there is no need for the control characters ( These might just be for pic AXE ) Try to communicate with it WITHOUT the 254 and 255 characters… Also in your move cursor function you are sending the internal address “0” twice…

In your other post about this I have also asked you to look at Christophe’s code on Fexzzer
[url]http://www.fezzer.com/project/180/i2c-execute-extension/[/url], and just try his code (for the same LCD display, and see how you get on…

Cheers Ian

There are three devices, there is the DS1307, the LCD, and a PICAXE chip which is what I believe I am trying to communicate with via i2c, and that drives the LCD module (Can’t think of any other reason it’d be there), cheers though I’ll try that out.

I’ve been thinking… In picaxe basic, is there only one i2cwrite cmd, or do they have i2cread as well… Reason for the thought is because of the 0xFF and 0xFE control characters… This seems to be a mask for the read / write bit.

Let me know if it works without these chars please…

Cheers Ian

Sure, Im not home, writing from my phone so couldn’t test it yet. I will have a look tomorrow :). And Picaxe basic also has an i2cread command.

by the way, as Im unsure about the way i2c works, has hte internal address got to be sent as a seperate transaction or not? and how do devices recognise between addresses and data? Do they just treat the first byte as address?

It seems as if most on this site reserve two bytes for the internal address… I wouldn’t use two transactions I’m not sure if that would work as the nature of the I2C protocol is to ack or nack after each transfer…

My experience with I2C is low level so I know how it works… Microsoft, however, masks all the low level operation from you… This allows you to set certain parameters the you need to just fill a buffer an send it, or create a buffer and let the device you’re talking to fill it.

If you have 2 transactions, you will just set the address pointer on the first transaction and then a stop… on the second transaction it should write the message as its getting the internal address and the string…

I have an I2C LCD at work… I also have a new panda on the way so I’ll get one up and running I will then know more.

Cheers Ian

Sorry for being late on this, but I don’t have much time those days :frowning:

Here’s what I would try to do a clear screen + display “Hello” :


I2CDevice.I2CTransaction[] ActionsLCD = new I2CDevice.I2CTransaction[1];
ActionsLCD[0] = I2CDevice.CreateWriteTransaction(new byte[4] { 0,0xFE, 1, 0xFF });
I2CDevice.Execute(xActions, 1000);
Thread.Sleep(30);
string Text = "Hello world !";
xActions[0] = I2C.CreateWriteTransaction(System.Text.Encoding.UTF8.GetBytes((byte)0 + Text+(byte)0xFF);
I2CDevice.Execute(xActions, 1000);
Thread.Sleep(30);

Not very easy to check without the device, though :wink:

Edit: there’s no need for Picaxe, here, or did I miss something ?

If this works, then you can almost copy/paste the code for the Devantech LCD03 from here :
http://www.fezzer.com/project/13/devantech-lcd03/

and simply add a 0xFF at the end of each transaction.

Cheers, still didn’t get time to test it though, the laptop that I have visual studio and all my drivers on is currently being used by my mother to watch movies :frowning:

I’m just wondering, if you send address in one transaction, and bytes in second, how does it know that the first byte of second transaction isnt another pointer? Also, are the transactions actually executed when you run the execute function, or when you assign them to xActions? I’m wondering this as I am unsure where to put my thread.sleeps in order to allow for processing time.

There is a start bit before address

None of this worked for me. I’m going to attempt to use the serial interface for the LCD screen, while using i2c for the ds1307 which is on the same board. Long way around doing it, but hopefully it’ll work.

EDIT: Thinking about it, the PICAXE runs at 5v, so maybe the problem is that the LCD requires a 5V signal for a high, and therefore isnt reading any of the data? Should i try putting FETs on the i2c lines?

EDIT 2: (From the pdf attached to first post)

Note the Serial LCD
does not buffer bytes received, and so a small delay between bytes (to update the
display) is required on non-PICAXE systems.

Does that mean that I should have a loop sending the bytes one by one, with something like thread.sleep(5) between each one?