Vol.893 26.Apr.2024

全顔料インクジェットプリンタ PICミニBB(3)_アナログ電圧入力ユニット

P 全顔料インクジェットプリンタ

by fjk

 長年使っていた全顔料インクジェットプリンタ(エプソン、PX504A、2010年製)のノズルの一部(3カ所)が詰まり、写真やベタ印刷時に筋が入るようになった(文字だけなら目立たないのだが・・)。そこで、ヘッドクリーニングを普段より多く繰り返してみたが、症状は変わらなかった。
 いよいよ寿命かと、代換えのプリンタを、以下の条件で探してみると、

1.インクは全て顔料インクで4色
・・・はがきや屋外印刷物用で、耐候性を重視
2.用紙サイズは最大A4で、前面給紙
・・・プリンタ後部に空きが必要ない
3.自動両面印刷
・・・自動両面印刷は必需
4.スキャナー・コピー(できればADF有)
・・・コピーがメインで、連続でできれば・・
5.接続IFはUSB、有線・無線LAN
・・・標準はUSBだが、LANでも使えたら・・
6.大きさはPX503A同等(w445xd367xh169)
・・・PX503A設置場所にそのまま置きたい

条件にマッチしたもので、さらに本体サイズを考慮すると、以下の2機種が候補となった

スペック DCP-J4143N(ブラザー) M730F(エプソン)
インク 4色顔料タンク 4色顔料カートリッジ
給紙トレイ前面151枚(A4) 前面250枚(A4)
両面印刷 自動両面印刷 自動両面印刷
スキャナーADF有り(2400dpi) ADF有り(2400dpi)
接続IF USB、有線/無線LAN USB、有線/無線LAN
大きさ w435、h180、d343 w425、h249、d379
価格(税込)29,000円〜(2023年発売)17,000円〜(2020年発売)

購入したDCP-J4143N

 価格を考えるとM730Fなのだが、大きさ(特に高さ)が気になり、パソコンラック(H=1150)上に設置していたPX503Aとほぼ同じ高さ(H=180)で、大容量ファーストタンク(カートリッジ10本以上相当)でインクが長持ちするので、DCP-J4143Nに決めた。印刷物は思っていたより色鮮やかだった。なお、レーベル・写真印刷には別の6色染料プリンタを使っている。

顔料インクと染料インクの違いなど
 顔料インク染料インク
インク粒子サイズ ・染料より大(紙の表面に定着) ・顔料より小(紙に染みこむ)
印刷物 ・滲みが少なく、輪郭がくっきりで
 ビジネス文書印刷向き
・光沢系の用紙が使え、発色が鮮やかで、
 写真印刷向き
寿 命 ・染料より耐水・耐候性が良
 色変化が少なく、長時間保存向き
・水に弱く、濡れると色が滲む
 光に当て続けると色あせする
レーベル印刷 ・できない ・できる
価 格 ・染料より高い ・顔料より安価


P PICミニBBシリーズ(3)  〜アナログ電圧入力ユニット

by fjk

 ミニBBシリーズ用に、アナログ電圧入力ユニットを作成した。これに伴いabc888で作成したLCDユニットのジャンパー配線に変更を加えた。

<変更箇所>
 ・RC2アナログ入力を外部に
 ・i2cコネクタ配置を以下の3種選択に
@VGDKV
(V:5V、G:Gnd)
AGDKVG
(D:SDA、K:SCK)
BDKVGN
(N:NC)

改良したLCDユニットの配線

 アナログ入力はPIC1825(PIC-BASE14)のRC2をアナログ入力とし、LCDユニット経由でアナログ入力ユニットに接続している。
 アナログ入力ユニットは、「基板取付用ボリューム」(10kΩ、秋月電子 114827、60円、+つまみ)と「ロータリコンコーダーDIP化基板」(AE-RECNV-1、秋月電子 107239、60円)を用い、ブレッドボードで使いやすいようにした(余分な配線もあるが、将来の拡張用)。


SPIC16F1825のSystemModule設定画面(16Mhz)

アナログ入力ユニットの配線

各ユニットの接続例

 今回、PIC-BASE14に16F1825を用いたが、16F18325と同じように、そのままMCCで作成するとエラーと警告が出る(コンパイラはC90を使用)。
 これは、以下の問題であり、その解決策は以下の通り。
  1. LCDライブラリで、1825のMSSP(i2c)は一つしか無いので「i2c1」ではなく「i2c」とする。
  2. プルアップ抵抗の設定は、pinモジュールのWPUの設定だけでなく、nWPUENもenabledにセットする必要がある

nWPUENをenableにセット
 なお、他のMCC設定で、
  • ピン設定でRC2の名称は「AN2」に、
  • RC0とRC1のWPUにチェック
  • ADCは「右詰め」に設定し、
  • EUSARTはabc889を参照。

MCCのADC設定画面

 また、printf文で浮動小数点データを使うとやはり多くのメモリ(97.1%)を使うので、別途作成したオリジナルライブラリ(my_stdlib.c/h)を使う(53.1%)と、メモリ使用量を減らすことができる。


printfを使用した場合

printfを使用しない場合

【プログラム】 abc893_1825.c(zip)

/*********************(abc893_1825.c)******
 *   アナログ入力
 ******************************************/

#include "mcc_generated_files/mcc.h"
#include "stdio.h"
#include "i2cLCD_ST7032i.h"
#include "my_stdlib.h"

/* -----  Variables  ----- */
char     	sBf[BFSIZE];     	// 文字列作業エリア
char     	rBuf[BFSIZE];     	// シリアル受信バッファ
uint8_t  	sFlg;             	// シリアル受信フラグ

/*=====    Main application   ===*/  

void main(void){
    uint16_t adC2;
    double	  volt;

    SYSTEM_Initialize();
    LCD_init();              	// LCD初期化    

    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    
    LCD_str("== ready ==");    

    while (1)
    {
        adC2 = ADC_GetConversion(AN6); 
        volt = (5.0 * adC2) / 1023.0;    
    //    sprintf(sBf,"%d %.2fv\r",adC2,volt);
        my_ftoa(sBf,(float)volt,2,2);
        puts(sBf);
        LCD_clr();
        LCD_str(sBf);
        IO_RA4_SetLow(); 
        __delay_ms(500);
        IO_RA4_SetHigh(); 
        __delay_ms(500);
    }
}
/** End of main File */

 
【文字列変換オリジナルライブラリ】 my_stdlib.c/h(zip)

/**************************************
 * 文字列変換ライブラリ(my_stdlib.c)
 **************************************/
#include "mcc_generated_files/mcc.h"
#include "string.h"
#include "my_stdlib.h"

/*------------------------------------------
 *   16進数文字列に変換
 *   uint16 -> str(Hex)
 *----------------------------------------*/
uint8_t my_utoa2(uint16_t n){
    n &= 0x0F;
    if(n < 10)  return '0'+ (uint8_t)n;
    else        return 'A'+ ((uint8_t)n - 10);
}

void my_utoa(uint8_t *str, uint16_t wd, uint8_t dg){
    if(dg > 3)  *str++ = my_utoa2(wd >> 12);
    if(dg > 2)  *str++ = my_utoa2(wd >> 8);
    if(dg > 1)  *str++ = my_utoa2(wd >> 4);
    *str++ = my_utoa2(wd);
    *str = '\0';
}

/*-----------------------------------------
 *   文字列を逆順に入替  
 *-----------------------------------------*/

void reverseString(char *str) {
    int length = (int)strlen(str);
    for (int i = 0; i < length / 2; i++) {
        char temp = str[i];
        str[i] = str[length - 1 - i];
        str[length - 1 - i] = temp;
    }
}

/*-----------------------------------------
 *   符号無し10進数文字列に変換
 *   uint16 -> str(Dec)
 *-----------------------------------------*/
void my_itoa2(char *str, uint16_t wd){
	for(int i = 0; i < 6; i++){
	  *str++ = '0' + (wd % 10);
	  wd = wd / 10;
	  if(wd == 0)	break;
	}
	*str = '\0';
}

void my_itoa(char *str, uint16_t wd){
	my_itoa2(str, wd);
	reverseString(str);
}

//--- 桁数指定文字列変換(符号無し) ---
void my_itoaN(char *str, uint16_t wd, uint8_t dg){
	str += dg;
	for(int i = dg; i > 0; i--){
		str--;
		*str = (wd % 10) + '0';
		wd = wd / 10;
	}
}

/*-------------------------------------------
 *   浮動小数点から文字列に変換
 *   float -> str(0.0)
 *------------------------------------------*/
void my_ftoa(char *str, float dat, uint8_t ip, int dp){
	int i;
	long dumy;
	str += ip;
	if(dp != 0){
		str += dp + 1;
	}
	str--;	
	for(i = 0; i < dp; i++){		//-- 整数化
		dat *= 10;
	}
	dumy = (long)(dat + 0.5);	
	for(i = dp; i > 0; i--){		//-- 小数部文字化
		*str-- =(uint8_t)(dumy %10)+'0';
		dumy /= 10;
	}
	if(dp != 0){				//-- 小数点付加
		*str-- = '.';
	}
	for(i = ip; i > 0; i--){		//-- 整数部文字化
		*str-- = (uint8_t)(dumy%10)+'0';
		dumy /= 10;	
	}
}
/** End of main File */

 
【LCD表示ライブラリ】 i2cLCD_ST7032i.c/h(zip)
(i2c)LCDライブラリ中にはmcc_exampleを使わないコード例も記述している。必要に応じて選択して下さい。

/******************************************
 *      LCD library  (i2cLCD_ST7032i.c)   *
 *      use for AQM0802A,AQM1602Y,....    *
 ******************************************/

#include "i2cLCD_ST7032i.h"

#define CONTRAST      0x18       // for 5.0V
//#define  CONTRAST   0x30       // for 3.3V
#define BOOST         0x00       // for 5.0V Bon=off
//#define  BOOST      0x04       // for 3.3V Bon=on

//-------- send command -------------------------
void LCD_cmd(char cmd){
/* ----- I2C_Write1ByteRegister()関数をを使わない場合
    uint8_t bf[2];
    bf[0] = 0x00;
    bf[1] = cmd;
    while(!I2C_Open(I2CLCD_Adr));
    I2C_SetBuffer(bf,2);
    I2C_MasterWrite();
    while(I2C_BUSY == I2C_Close());
 */
    I2C_Write1ByteRegister(I2CLCD_Adr, 0x00, cmd);
//-- Clear かHomeか?
    if(cmd & 0xFC)              // bit6 = 1
        __delay_us(30);         // 30us
    else
        __delay_ms(2);          // 2ms Clear or Home
}

//-------- send data ----------------------
void LCD_dat(char chr){
/* ---- I2C_Write1ByteRegister()関数を使わない場合 
    uint8_t bf[2];
    bf[0] = 0x40;
    bf[1] = chr;
    while(!I2C_Open(I2CLCD_Adr));
    I2C_SetBuffer(bf,2);
    I2C_MasterWrite();
    while(I2C_BUSY == I2C_Close());
 */
    I2C_Write1ByteRegister(I2CLCD_Adr, 0x40, chr);
    __delay_us(30);              // 30us
}

//-------- clear LCD--------------------------
void LCD_clr(void){
    LCD_cmd(0x01);
}

//--------- Home -----------------------------
void LCD_home(void){
    LCD_cmd(0x02);
}

//--------- Cursor X,Y -----------------------
void LCD_cursor(int x, int y){
    if (y == 0)
        LCD_cmd((char)(0x80 + x));
    else if (y == 1)
        LCD_cmd((char)(0xc0 + x));
}

//-------- display strings -------------------------
void LCD_str(char *str){
    while(*str)
 	LCD_dat(*str++); //pointer increment
}

//------- Create CG Char ---------
uint8_t LCD_CGchar(uint8_t c, char* dt){
    uint8_t i;
	if(c > 7) return 1;
	LCD_cmd((char)(0x40 | (c << 3)));
	__delay_us(30);
	for(i = 0; i < 7; i++){
		LCD_dat(*dt++);
	    __delay_us(30);
	}
	return 0;
}

//-------- LCD sift position -----------------
void LCD_sift(uint8_t d){
	if(d) LCD_cmd(0x18);
	else  LCD_cmd(0x1C);    
}

//-------- LCD initialize ---------------------------
void LCD_init(void){
    __delay_ms(40);         // 40ms wait
    LCD_cmd(0x38);          // 8bit,2line
    LCD_cmd(0x39);          // IS=1 : extention mode set
    LCD_cmd(0x14);          // Internal OSC Frequency
    LCD_cmd(0x70 + (CONTRAST & 0x0F)); 	//Contrast set
    LCD_cmd(0x58 + BOOST + (CONTRAST >> 4));
                            //Power/ICON/Contrast Control
    LCD_cmd(0x6C);          // Follower control
    __delay_ms(200);        // 200ms wait
    LCD_cmd(0x38);          // IS=0 : extention mode cancel
    LCD_cmd(0x0C);          // Display ON
    LCD_cmd(0x01);          // Clear Display
    __delay_ms(2);          // wait more than 1.08ms
}

//-------- Redirect STDIO to LCD ----------------
/*
void putch(char ch){
    LCD_dat(ch);
}
*/

/********  End of File ******/


※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。


全顔料インクジェットプリンタ PICミニBB(3)_アナログ電圧入力ユニット