I2c Write issue on ic ch455

Hey. I am using a keypad having an ic 455g which is installed in an infusion pump. this keypad is used to enter an infusion rate. I have decoded all keys and know the code generated by each key. now i want to write a data on that ic ch455g but issue is this it is not writing anything. I have written a write program but it is functioning as a read program the register addresses provided by data sheets are 68H, 6AH, 6CH or 6EH. my code is as follow

#include <Wire.h>
uint8_t data;
void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  Serial.begin(9600);
      Wire.beginTransmission(0x24);
  Wire.write(0x68);
  Wire.write(0x0A);
  Wire.endTransmission();
  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:


Wire.beginTransmission(0x24);
  Wire.write(0x4F);
  Wire.endTransmission();

  Wire.requestFrom(0x24, 1,true);
  
   data = Wire.read(); 
    Serial.print("read ");
  Serial.println(data,HEX);
   delay(1000);
  
  }
``

I moved your topic to an appropriate forum category @muhammad_faizan_khan.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

I will read it and post according to category. Thanks

1 Like

It'll help if you have documentation of this module. There are a number of ways this can be implemented and especially a schematic of the module you're using would help.

Have you tried the other digits as well? Do none of them work?

Also, have you tried setting the System Parameter Commands (section 6.1 in the datasheet)? I don't see this reflected in your code.

I have to say that the documentation of the CH455 isn't so great and the programming examples they promise in the datasheet aren't easily found on the website (I've not been able to find them so far, at least).

The manufacturer's page of the CH455: https://wch-ic.com/products/CH455.html

Where I can find example code and explanation of the registers ?

Apparently, you don't. It seems that the documentation isn't particularly well maintained. The datasheet does offer some explanation on the registers, but the information isn't very consistent/clear/complete.

i have tried other digits as well but still didn't get anything.

System Parameter Commands (section 6.1 in the datasheet)? can you please guide me about it?

there isn't any code

I can't guide you any more than what the datasheet says in section 6.1. I glanced over that section and it seems to give some relevant info about getting the chip in and out of sleep mode, how the display segments are addressed, brightness etc. It seems relatively straightforward, except for the somewhat opaque formulation of the text.

The code provided by the manufacturer are as follow:
CH455I2C.c

/* ***************************
 Website:  http://wch.cn
 Email:    tech@wch.cn
 Author:   W.ch 2008.7
* ****************************/
#include	"CH455I2C.H"		// Ð޸ĸÃÎļþÒÔÊÊÓ¦Ó²¼þ»·¾³/µ¥Æ¬»úÐͺŵÈ
#include <reg52.H>
#include <INTRINS.h>

void CH455_I2c_Start( void )  // ²Ù×÷Æðʼ
{
	DISABLE_KEY_INTERRUPT;  //½ûÖ¹¼üÅÌÖжÏ,·ÀÖ¹¿ªÊ¼Ê±±»CH455Öж϶ø½øÈëÖжϷþÎñ³ÌÐòÖеÄSTART
	CH455_SDA_SET;   /*·¢ËÍÆðʼÌõ¼þµÄÊý¾ÝÐźÅ*/
	CH455_SDA_D_OUT;   /* ÉèÖÃSDAΪÊä³ö·½Ïò */
	CH455_SCL_SET;
	CH455_SCL_D_OUT;   /* ÉèÖÃSCLΪÊä³ö·½Ïò */
	DELAY;
	CH455_SDA_CLR;   /*·¢ËÍÆðʼÐźÅ*/
	DELAY;      
	CH455_SCL_CLR;   /*ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý */
}

void CH455_I2c_Stop( void )  // ²Ù×÷½áÊø
{
	CH455_SDA_CLR;
	CH455_SDA_D_OUT;   /* ÉèÖÃSDAΪÊä³ö·½Ïò */
	DELAY;
	CH455_SCL_SET;
	DELAY;
	CH455_SDA_SET;  /*·¢ËÍI2C×ÜÏß½áÊøÐźÅ*/
	DELAY;
	CH455_SDA_D_IN;   /* ÉèÖÃSDAΪÊäÈë·½Ïò */
	ENABLE_KEY_INTERRUPT;
}

void CH455_I2c_WrByte( UINT8 dat )	//дһ¸ö×Ö½ÚÊý¾Ý
{
	UINT8 i;
	CH455_SDA_D_OUT;   /* ÉèÖÃSDAΪÊä³ö·½Ïò */
	for( i = 0; i != 8; i++ )  // Êä³ö8λÊý¾Ý
	{
		if( dat & 0x80 ) 
		{
		    CH455_SDA_SET;
		}
		else 
		{
		    CH455_SDA_CLR;
		}
		DELAY;
		CH455_SCL_SET;
		dat <<= 1;
		DELAY;  // ¿ÉÑ¡ÑÓʱ
		CH455_SCL_CLR;
	}
	CH455_SDA_D_IN;   /* ÉèÖÃSDAΪÊäÈë·½Ïò */
	CH455_SDA_SET;
	DELAY;
	CH455_SCL_SET;  // ½ÓÊÕÓ¦´ð
	DELAY;
	CH455_SCL_CLR;
}

UINT8  CH455_I2c_RdByte( void )		//¶ÁÒ»¸ö×Ö½ÚÊý¾Ý
{
	UINT8 dat,i;
	CH455_SDA_SET;
	CH455_SDA_D_IN;   /* ÉèÖÃSDAΪÊäÈë·½Ïò */
	dat = 0;
	for( i = 0; i != 8; i++ )  // ÊäÈë8λÊý¾Ý
	{
		DELAY;  // ¿ÉÑ¡ÑÓʱ
		CH455_SCL_SET;
		DELAY;  // ¿ÉÑ¡ÑÓʱ
		dat <<= 1;
		if( CH455_SDA_IN ) dat++;  // ÊäÈë1λ
		CH455_SCL_CLR;
	}
	CH455_SDA_SET;
	DELAY;
	CH455_SCL_SET;  // ·¢³öÎÞЧӦ´ð
	DELAY;
	CH455_SCL_CLR;
	return dat;
}

void CH455_Write( UINT16 cmd )	//дÃüÁî
{
	CH455_I2c_Start();               //Æô¶¯×ÜÏß
   	CH455_I2c_WrByte(((UINT8)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR);
   	CH455_I2c_WrByte((UINT8)cmd);               //·¢ËÍÊý¾Ý
  	CH455_I2c_Stop();                 //½áÊø×ÜÏß 
}

UINT8 CH455_Read( void )		//¶ÁÈ¡°´¼ü
{
	UINT8 keycode;
   	CH455_I2c_Start();                //Æô¶¯×ÜÏß
   	CH455_I2c_WrByte((UINT8)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR);
   	keycode=CH455_I2c_RdByte();      //¶ÁÈ¡Êý¾Ý
	CH455_I2c_Stop();                //½áÊø×ÜÏß
	return keycode;
}



CH455.h

// Ó²¼þÏà¹Ø¶¨Òå, Çë¸ù¾Ýʵ¼ÊÓ²¼þÐ޸ı¾Îļþ
#include <reg52.h>
#pragma NOAREGS		// Èç¹ûMCS51ÔÚÖжϷþÎñ³ÌÐòÖе÷ÓÃCH455×Ó³ÌÐò»òÕßʹÓüüÅÌÖжϹ¦ÄÜ£¬ÄÇô½¨Òé¼ÓÈë´Ë±àÒëÑ¡Ïî

#define		DELAY		{ _nop_();_nop_();_nop_();_nop_(); }	

typedef unsigned char   UINT8;
typedef unsigned short  UINT16;	

/* 2Ïß½Ó¿ÚµÄÁ¬½Ó,Óëʵ¼Êµç·ÓÐ¹Ø */
sbit	CH455_SCL = P1^7;
sbit	CH455_SDA = P1^6;
sbit	CH455_INT = P3^3;   // ±ê×¼µÄ2Ïß½Ó¿ÚʹÓøÃÒý½ÅÊä³öÖжÏ

/* 2Ïß½Ó¿ÚµÄλ²Ù×÷,Ó뵥Ƭ»úÓÐ¹Ø */
#define		CH455_SCL_SET		{CH455_SCL=1;}
#define		CH455_SCL_CLR		{CH455_SCL=0;}
#define		CH455_SCL_D_OUT		{}				// ÉèÖÃSCLΪÊä³ö·½Ïò,¶ÔÓÚË«ÏòI/OÐèÇл»ÎªÊä³ö
#define		CH455_SDA_SET		{CH455_SDA=1;}
#define		CH455_SDA_CLR		{CH455_SDA=0;}
#define		CH455_SDA_IN		(CH455_SDA)
#define		CH455_SDA_D_OUT		{}				// ÉèÖÃSDAΪÊä³ö·½Ïò,¶ÔÓÚË«ÏòI/OÐèÇл»ÎªÊä³ö
#define		CH455_SDA_D_IN		{CH455_SDA=1;}	// ÉèÖÃSDAΪÊäÈë·½Ïò,¶ÔÓÚË«ÏòI/OÐèÇл»ÎªÊäÈë

/* Ó뵥Ƭ»úÓйØ,ÓëÖжÏÁ¬½Ó·½Ê½ÓÐ¹Ø */
#define		USE_CH455_KEY		1			// ʹÓÃÁËCH455µÄ°´¼üÖжÏ

#ifdef USE_CH455_KEY
	#define		DISABLE_KEY_INTERRUPT	{EX1=0;}
	#define		ENABLE_KEY_INTERRUPT	{EX1=1;}
	#define		CLEAR_KEY_INTER_FLAG	{IE1=0;}
#else
	#define		DISABLE_KEY_INTERRUPT	{}
	#define		ENABLE_KEY_INTERRUPT	{}
	#define		CLEAR_KEY_INTER_FLAG	{}
#endif

/* ********************************************************************************************* */
// ÉèÖÃϵͳ²ÎÊýÃüÁî

#define CH455_BIT_ENABLE	0x01		// ¿ªÆô/¹Ø±Õλ
#define CH455_BIT_SLEEP		0x04		// ˯Ãß¿ØÖÆλ
#define CH455_BIT_7SEG		0x08		// 7¶Î¿ØÖÆλ
#define CH455_BIT_INTENS1	0x10		// 1¼¶ÁÁ¶È
#define CH455_BIT_INTENS2	0x20		// 2¼¶ÁÁ¶È
#define CH455_BIT_INTENS3	0x30		// 3¼¶ÁÁ¶È
#define CH455_BIT_INTENS4	0x40		// 4¼¶ÁÁ¶È
#define CH455_BIT_INTENS5	0x50		// 5¼¶ÁÁ¶È
#define CH455_BIT_INTENS6	0x60		// 6¼¶ÁÁ¶È
#define CH455_BIT_INTENS7	0x70		// 7¼¶ÁÁ¶È
#define CH455_BIT_INTENS8	0x00		// 8¼¶ÁÁ¶È

#define CH455_SYSOFF	0x0400			// ¹Ø±ÕÏÔʾ¡¢¹Ø±Õ¼üÅÌ
#define CH455_SYSON		( CH455_SYSOFF | CH455_BIT_ENABLE )	// ¿ªÆôÏÔʾ¡¢¼üÅÌ
#define CH455_SLEEPOFF	CH455_SYSOFF	// ¹Ø±Õ˯Ãß
#define CH455_SLEEPON	( CH455_SYSOFF | CH455_BIT_SLEEP )	// ¿ªÆô˯Ãß
#define CH455_7SEG_ON	( CH455_SYSON | CH455_BIT_7SEG )	// ¿ªÆôÆ߶Îģʽ
#define CH455_8SEG_ON	( CH455_SYSON | 0x00 )	// ¿ªÆô°Ë¶Îģʽ
#define CH455_SYSON_4	( CH455_SYSON | CH455_BIT_INTENS4 )	// ¿ªÆôÏÔʾ¡¢¼üÅÌ¡¢4¼¶ÁÁ¶È
#define CH455_SYSON_8	( CH455_SYSON | CH455_BIT_INTENS8 )	// ¿ªÆôÏÔʾ¡¢¼üÅÌ¡¢8¼¶ÁÁ¶È


// ¼ÓÔØ×ÖÊý¾ÝÃüÁî
#define CH455_DIG0		0x1400			// ÊýÂë¹Üλ0ÏÔʾ,ÐèÁí¼Ó8λÊý¾Ý
#define CH455_DIG1		0x1500			// ÊýÂë¹Üλ1ÏÔʾ,ÐèÁí¼Ó8λÊý¾Ý
#define CH455_DIG2		0x1600			// ÊýÂë¹Üλ2ÏÔʾ,ÐèÁí¼Ó8λÊý¾Ý
#define CH455_DIG3		0x1700			// ÊýÂë¹Üλ3ÏÔʾ,ÐèÁí¼Ó8λÊý¾Ý



// ¶ÁÈ¡°´¼ü´úÂëÃüÁî
#define CH455_GET_KEY	0x0700					// »ñÈ¡°´¼ü,·µ»Ø°´¼ü´úÂë


// CH455½Ó¿Ú¶¨Òå
#define		CH455_I2C_ADDR		0x40			// CH455µÄµØÖ·
#define		CH455_I2C_MASK		0x3E			// CH455µÄ¸ß×Ö½ÚÃüÁîÑÚÂë

// ¶ÔÍâ×Ó³ÌÐò
extern	UINT8 CH455_Read( void );				// ´ÓCH455¶ÁÈ¡°´¼ü´úÂë
extern  void CH455_Write( UINT16 cmd );	// ÏòCH455·¢³ö²Ù×÷ÃüÁî

Main.C

/* ***************************
 Website:  http://wch.cn
 Email:    tech@wch.cn
 Author:   W.ch 2008.7
* ****************************/
#include <reg52.h>
#include "CH455I2C.H"	// Ð޸ĸÃÎļþÒÔÊÊÓ¦Ó²¼þ»·¾³/µ¥Æ¬»úÐͺŵÈ

UINT8 ch455_key;//CH455µÄ°´¼ü¼üÖµ

const UINT8 BCD_decode_tab[0x10] = { 0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 
									 0X77, 0X7C, 0X58, 0X5E, 0X79, 0X71 };//BCD

void mDelaymS( UINT8 ms )// ÑÓʱºÁÃë
{
	UINT16 i;
	while ( ms -- ) 
	{
		for( i = 0; i != 1000; i++ );
	}
}

void init_CH455( void ) //³õʼ»¯CH455
{
#ifdef USE_CH455_KEY
	IE1=0;
	EX1=1;
	EA=1;
#endif
}

void int1( void ) interrupt 2 using 1 // INT0ÖжϷþÎñ³ÌÐò
{
	ch455_key = CH455_Read();
}

void main( void )//Ö÷³ÌÐò
{
	UINT8 i;
    UINT8 showH[2],showL[2];

	mDelaymS( 40 );
	init_CH455();//³õʼ»¯

	CH455_Write( CH455_SYSON );// ¿ªÆôÏÔʾºÍ¼üÅÌ£¬8¶ÎÏÔʾ·½Ê½

	//·¢ÏÔʾÊý¾Ý
	CH455_Write( CH455_DIG0 | BCD_decode_tab[0] );	
	CH455_Write( CH455_DIG1 | BCD_decode_tab[1] ); 
	CH455_Write( CH455_DIG2 | BCD_decode_tab[2] ); 
	CH455_Write( CH455_DIG3 | BCD_decode_tab[3] ); 

    //ÁÁ¶È±ä»¯
    for( i = 1; i < 8; i++ )
	{
	     mDelaymS( 50 );
 	     CH455_Write( CH455_SYSON | i<<4 );	// 1-7¼¶ÁÁ¶ÈÏÔʾ
    }
	mDelaymS( 50 );
	CH455_Write( CH455_SYSON_8 );	// 8¼¶ÁÁ¶ÈÏÔʾ

	//4λÊýÂë¹ÜÈ«²¿ÏÔʾ0
	showL[0] = BCD_decode_tab[0];
	showH[0] = BCD_decode_tab[0];
	showL[1] = BCD_decode_tab[0];
	showH[1] = BCD_decode_tab[0];
	CH455_Write( CH455_DIG3 | showL[0] );	
	CH455_Write( CH455_DIG2 | showH[0] ); 
	CH455_Write( CH455_DIG1 | showL[1] ); 
	CH455_Write( CH455_DIG0 | showH[1] ); 
    
    
	while(1)
	{
	#ifdef USE_CH455_KEY
		 ch455_key = 0xff;
		 while( ch455_key == 0xff );

		 i = ch455_key & 0x3f;//°´¼üÖµ

		 //ÊýÂë¹ÜÏÔʾ֮¼äµÄÒÆλ²Ù×÷
		 showH[1] = showH[0];
		 showL[1] = showL[0];
		 showH[0] = BCD_decode_tab[i/10];
		 showL[0] = BCD_decode_tab[i%10];
         CH455_Write( CH455_DIG3 | showL[0] );	
	     CH455_Write( CH455_DIG2 | showH[0] ); 
	     CH455_Write( CH455_DIG1 | showL[1] ); 
	     CH455_Write( CH455_DIG0 | showH[1] );

		 //Åжϰ´¼üÓÐûÓÐÊÍ·Å
		 while(1)
		 {
		      i = CH455_Read( );//¶Á°´¼üÊýÖµ
			  if( i & 0x40 )//°´¼ü°´ÏÂûÓÐÊÍ·Å
			  {
			      //ÉÁ˸
			      CH455_Write( CH455_DIG3 );	
	              CH455_Write( CH455_DIG2 );
                  mDelaymS(50);
				  CH455_Write( CH455_DIG3 | showL[0] );	
	              CH455_Write( CH455_DIG2 | showH[0] );
			      mDelaymS(50);
			  }
			  else//°´¼üÒѾ­ÊÍ·Å
			  {
			      break;
			  }
		  }

    #endif
	}
												
}

but still i didnt get it. i am newbie so i cannot upload file now thats why i have pasted code here .

[quote="muhammad_faizan_khan, post:11, topic:1249671"]i cannot upload file now thats why i have pasted code
[/quote]
That's OK, but could you please edit your post so that each individual code file you pasted has its own code block?

Like this:

Code in file 1
Code in file 2

Etc.

Also, the code is written in C, not C++ as used on Arduino platforms, so it needs to reworked a bit in order to work with Arduino. On the other hand, they do some things manually that you can do easier in Arduino; e.g. they have a 'bit-banged' I2C library (your first file) that you can pretty much ignore and replace with Arduino's Wire library functions, which are a little more user-friendly.

I have separated the code please check

Thanks, that looks better!

Note what happens here:

The 'SYSON' bit is apparently the startup routine that powers on the display. It's defined as 0x0400, which you can relate to the datasheet to see which register bits are being set.

The other 4 lines I quoted apparently print a number to each of the four digits on the display.

Hi

To operate ch455g , it is not necessary to know the exact register address.

The communication process between MCU and CH455 is always divided into 6 steps, which are divided into two types according to the operation direction of MCU, one is write operation for outputting data, and the other is read operation for inputting data. The specific process can refer to the description in the example program.

The write operation consists of the following 6 steps: output start signal, output byte 1, answer 1, output byte 2, answer 2, and output stop signal. Please read section 5.4 of the datasheet.

The operation commands of CH455 are divided into 3 groups. The start signal, stop signal, answer 1 and answer 2 are the same for each command, but the difference is that the data of output byte 1 and byte 2 are different, and the transmission direction of byte 2 is different. For the operation commands, please read chapter 6 of the data sheet.

Best Regards,
manuafacturer replied me this

That's just I2C. Arduino Wire handles this for you for the most part.

Yes, again, that's generic I2C. Start & stop are the same for all devices since they're standardized in the I2C protocol, so is Ack ('answer 1' and '2').

Right. So that gets us back to where we started.

I'd say a polite "thanks" to the person who sent you the mail above; it's probably well-intended, but it doesn't help much.

However, the code that they shared definitely is extremely useful! Have you already tried implementing the bit I quoted in #14 in your own sketch?

Manufacturer replied me this

Hi

Writing data for the keys does not work, the chip can only scan which keys have been pressed, while the key code can be read through the serial interface.

Best Regards,

Yes, that follows from the datasheet. You can actually set the CH455 to read the keys or to skip reading the keys. Of course you can't write to the keys.

yes you are right. Thanks for your help

can you please tell me whether we can change address of arduino or not? i want my arduino adress to be 0x24