XYZPrinting达芬奇是一个非常有趣的打印机。它提供了一个只有300g材料盒,打完就要换原厂的材料盒(有一个芯片保存了材料盒中材料的存量)。 这篇教程教怎么在使用外部材料的情况下刷新原厂的芯片中的材料存量。
背景知识
打开墨盒后,可以在其底部找到一个小PCB。它有三个连接器用于与打印机本身进行通信。仔细检查该微小PCB显示了Microchip 11LC010 1K EEPROM的核心。该EEPROM具有128字节的存储容量,其存储关于长丝盒的信息。 SCIO引脚运行UNI / O协议,芯片通过8位指令寄存器进行控制。
步骤
0. 将打印机的墨盒拿出来,找到底部的芯片 1. 创建一个的Arduino程序(程序已经写好见附件),程序可以写入EEPROM的内容,把计数器重置为999m剩余可用材料。 这里是EEPROM的内容。 您可以在字节偏移53处看到一个小字节格式的4字节长HEX值,这反映了传送给打印机的剩余长丝长度。这不是一个字面值,而是以某种方式“被破坏”。但是,将此值设置为0x3f420f00将灯丝计数器恢复为剩余999m。(想要复写计数器就保持默认)
00:5A41570000343141C0D40100C0D40100 ZAW..41A ...... ..
10:D2005A00544847423031313500000000 ..Z.THGB0115 ...。
20:000000003400000001010101AA55AA55 ... .4 ...... ..UU
30:883355AA 3F420f00 D04407202FAE0A00 .3U ...... D。/ ...
40:5A41570000343141C0D40100C0D40100 ZAW..41A ...... ..
50:D2005A00544847423031313500000000 ..Z.THGB0115 ...。
60:000000003400000001010101AA55AA55 ... .4 ...... ..UU
70:883355AAC0D40100AA55AA5507830A00 .3U ...... UU ...。
2. 写入Arduino该程序
写入没有开始时,Arduino上的LED会闪烁。
3. 以一下方式分别连接Arduino上的引脚和材料盒子上的触点
三个连接器如下(从上图的左到右):
4. 按照上述方法进行上述连接后,LED将保持点亮约2秒,然后闪烁一下,表示EEPROM已成功写入。5. 实际测试是否可以打印,如果显示Unidentified Cartridge的错误,重新从0步骤开始刷芯片
参考https://www.voltivo.com/da-vinci ... t-using-an-arduino/
程序:
- #ifndef _NANODEUNIO_LIB_H
- #define _NANODEUNIO_LIB_H
- #if ARDUINO >= 100
- #include <Arduino.h> // Arduino 1.0
- #else
- #include <WProgram.h> // Arduino 0022
- #endif
- #define NANODE_MAC_DEVICE 0xa0
- #define NANODE_MAC_ADDRESS 0xfa
- #define CODE 0x00 //1 Byte
- #define MATERIAL 0x01 //1 Byte
- #define COLOR 0x02 //2 Bytes
- #define DATE 0x05 //4 Bytes
- #define TOTALLEN 0x08 //4 Bytes
- #define NEWLEN 0x0C //4 Bytes
- #define HEADTEMP 0x10 //2 Bytes
- #define BEDTEMP 0x12 //2Bytes
- #define MLOC 0x14 //2 Bytes
- #define DLOC 0x16 //2 Bytes
- #define SN 0x18 //12 Bytes
- #define CRC 0x24 //2 Bytes
- #define LEN2 0x34 //4 Bytes
- #define EOFM 0x38 //4 Bytes
- #define SCODE 0x3c //4 Bytes
- void IncrementSerial(unsigned char * cArray, long lAddress, long lSize)
- {
- unsigned char szTempBuffer[20] = {0};
- memcpy(szTempBuffer,&cArray[lAddress],lSize);
- long lSerial = atol((char *)szTempBuffer);
- lSerial++;
- sprintf((char *)szTempBuffer,"%04d",lSerial);
- memcpy(&cArray[lAddress],szTempBuffer,lSize);
- }
- class NanodeUNIO {
- private:
- byte addr;
- public:
- NanodeUNIO(byte address);
- boolean read(byte *buffer,word address,word length);
- boolean start_write(const byte *buffer,word address,word length);
- boolean enable_write(void);
- boolean disable_write(void);
- boolean read_status(byte *status);
- boolean write_status(byte status);
- boolean await_write_complete(void);
- boolean simple_write(const byte *buffer,word address,word length);
- };
- #endif /* _NANODEUNIO_LIB_H */
- #define UNIO_STARTHEADER 0x55
- #define UNIO_READ 0x03
- #define UNIO_CRRD 0x06
- #define UNIO_WRITE 0x6c
- #define UNIO_WREN 0x96
- #define UNIO_WRDI 0x91
- #define UNIO_RDSR 0x05
- #define UNIO_WRSR 0x6e
- #define UNIO_ERAL 0x6d
- #define UNIO_SETAL 0x67
- #define UNIO_TSTBY 600
- #define UNIO_TSS 10
- #define UNIO_THDR 5
- #define UNIO_QUARTER_BIT 10
- #define UNIO_FUDGE_FACTOR 5
- #define UNIO_OUTPUT() do { DDRD |= 0x80; } while (0)
- #define UNIO_INPUT() do { DDRD &= 0x7f; } while (0)
- static void set_bus(boolean state) {
- PORTD=(PORTD&0x7f)|(!!state)<<7;
- }
- static boolean read_bus(void) {
- return !!(PIND&0x80);
- }
- static void unio_inter_command_gap(void) {
- set_bus(1);
- delayMicroseconds(UNIO_TSS+UNIO_FUDGE_FACTOR);
- }
- static void unio_standby_pulse(void) {
- set_bus(0);
- UNIO_OUTPUT();
- delayMicroseconds(UNIO_TSS+UNIO_FUDGE_FACTOR);
- set_bus(1);
- delayMicroseconds(UNIO_TSTBY+UNIO_FUDGE_FACTOR);
- }
- static volatile boolean rwbit(boolean w) {
- boolean a,b;
- set_bus(!w);
- delayMicroseconds(UNIO_QUARTER_BIT);
- a=read_bus();
- delayMicroseconds(UNIO_QUARTER_BIT);
- set_bus(w);
- delayMicroseconds(UNIO_QUARTER_BIT);
- b=read_bus();
- delayMicroseconds(UNIO_QUARTER_BIT);
- return b&&!a;
- }
- static boolean read_bit(void) {
- boolean b;
- UNIO_INPUT();
- b=rwbit(1);
- UNIO_OUTPUT();
- return b;
- }
- static boolean send_byte(byte b, boolean mak) {
- for (int i=0; i<8; i++) {
- rwbit(b&0x80);
- b<<=1;
- }
- rwbit(mak);
- return read_bit();
- }
- static boolean read_byte(byte *b, boolean mak) {
- byte data=0;
- UNIO_INPUT();
- for (int i=0; i<8; i++) {
- data = (data << 1) | rwbit(1);
- }
- UNIO_OUTPUT();
- *b=data;
- rwbit(mak);
- return read_bit();
- }
- static boolean unio_send(const byte *data,word length,boolean end) {
- for (word i=0; i<length; i++) {
- if (!send_byte(data[i],!(((i+1)==length) && end))) return false;
- }
- return true;
- }
- static boolean unio_read(byte *data,word length) {
- for (word i=0; i<length; i++) {
- if (!read_byte(data+i,!((i+1)==length))) return false;
- }
- return true;
- }
- static void unio_start_header(void) {
- set_bus(0);
- delayMicroseconds(UNIO_THDR+UNIO_FUDGE_FACTOR);
- send_byte(UNIO_STARTHEADER,true);
- }
- NanodeUNIO::NanodeUNIO(byte address) {
- addr=address;
- }
- #define fail() do { sei(); return false; } while (0)
- boolean NanodeUNIO::read(byte *buffer,word address,word length) {
- byte cmd[4];
- cmd[0]=addr;
- cmd[1]=UNIO_READ;
- cmd[2]=(byte)(address>>8);
- cmd[3]=(byte)(address&0xff);
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,4,false)) fail();
- if (!unio_read(buffer,length)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::start_write(const byte *buffer,word address,word length) {
- byte cmd[4];
- if (((address&0x0f)+length)>16) return false; // would cross page boundary
- cmd[0]=addr;
- cmd[1]=UNIO_WRITE;
- cmd[2]=(byte)(address>>8);
- cmd[3]=(byte)(address&0xff);
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,4,false)) fail();
- if (!unio_send(buffer,length,true)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::enable_write(void) {
- byte cmd[2];
- cmd[0]=addr;
- cmd[1]=UNIO_WREN;
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,2,true)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::disable_write(void) {
- byte cmd[2];
- cmd[0]=addr;
- cmd[1]=UNIO_WRDI;
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,2,true)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::read_status(byte *status) {
- byte cmd[2];
- cmd[0]=addr;
- cmd[1]=UNIO_RDSR;
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,2,false)) fail();
- if (!unio_read(status,1)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::write_status(byte status) {
- byte cmd[3];
- cmd[0]=addr;
- cmd[1]=UNIO_WRSR;
- cmd[2]=status;
- unio_standby_pulse();
- cli();
- unio_start_header();
- if (!unio_send(cmd,3,true)) fail();
- sei();
- return true;
- }
- boolean NanodeUNIO::await_write_complete(void) {
- byte cmd[2];
- byte status;
- cmd[0]=addr;
- cmd[1]=UNIO_RDSR;
- unio_standby_pulse();
- do {
- unio_inter_command_gap();
- cli();
- unio_start_header();
- if (!unio_send(cmd,2,false)) fail();
- if (!unio_read(&status,1)) fail();
- sei();
- } while (status&0x01);
- return true;
- }
- boolean NanodeUNIO::simple_write(const byte *buffer,word address,word length) {
- word wlen;
- while (length>0) {
- wlen=length;
- if (((address&0x0f)+wlen)>16) {
- wlen=16-(address&0x0f);
- }
- if (!enable_write()) return false;
- if (!start_write(buffer,address,wlen)) return false;
- if (!await_write_complete()) return false;
- buffer+=wlen;
- address+=wlen;
- length-=wlen;
- }
- return true;
- }
- static void status(boolean r)
- {
- if (r) Serial.println("(success)");
- else Serial.println("(failure)");
- }
- static void dump_eeprom(word address,word length)
- {
- byte buf[128];
- char lbuf[80];
- char *x;
- int i,j;
- NanodeUNIO unio(NANODE_MAC_DEVICE);
-
- memset(buf,0,128);
- status(unio.read(buf,address,length));
-
- for (i=0; i<128; i+=16) {
- x=lbuf;
- sprintf(x,"%02X: ",i);
- x+=4;
- for (j=0; j<16; j++) {
- if (!(j & 0x03)) {
- sprintf(x, " ");
- x+=1;
- }
- sprintf(x,"%02X",buf[i+j]);
- x+=2;
- }
- *x=32;
- x+=1;
- for (j=0; j<16; j++) {
- if (buf[i+j]>=32 && buf[i+j]<127) *x=buf[i+j];
- else *x=46;
- x++;
- }
- *x=0;
- Serial.println(lbuf);
- }
- }
- int led = 13;
- /*
- These are the values to be written to the EEPROM
- Make sure only one is uncommented.
- By default its set for the starter ABS cartdridge with 120m of filament
- Verified with firmware 1.1.I
- */
- // Value to write to the EEPROM for remaining filament lenght
- // Default Starter Cartdridge is 120m
- //char x[] = {0xc0,0xd4,0x01,0x00}; //120m
- char x[] = {0x80,0xa9,0x03,0x00}; //240m
- //char x[] = {0x80,0x1a,0x06,0x00}; //400m
- // extruder temp, default is 210 C for ABS
- // 180 C for PLA
- //char et[] = {0xb4,0x00}; // 180 C
- //char et[] = {0xb9,0x00}; // 185 C
- //char et[] = {0xbe,0x00}; // 190 C
- //char et[] = {0xc8,0x00}; // 200 C
- //char et[] = {0xd2,0x00}; // 210 C
- char et[] = {0xe6,0x00}; // 230 C
- //char et[] = {0xf5,0x00}; // 245 C
- //char et[] = {0xfa,0x00}; // 250 C
- // bed temp 90 degrees, default ABS
- // 30 degrees foe PLA
- char bt[] = {0x5a,0x00}; // 90 C
- //char bt[] = {0x1e,0x00}; // 30 C
- char cc[] = {0xa7,0x06,0x0b,0x00}; //seems to be relavent to the first 5 characters of Serial number. In this case RF10X
- //char cc[] = {0x07,0x83,0x0a,0x00}; // for serial number beginning with 3DP01
- char ef[] = {0xaa,0x55,0xaa,0x55};
- char mt[] = {0x41}; // Material - "A" for ABS
- //char mt[] = {0x50}; // Material - "P" for PLA
- char cr[] = {0x5a,0x00}; // COLOUR - Default-0x5a,0x00 [White-0x57,0x00 Blue-0x42,0x00 Green-0x47,0x00 Black-0x4B,0x00 Red-0x52,0x00 Yellow-0x59,0x00 VirginViolet-0x43,0x00]
- byte sr;
- NanodeUNIO unio(NANODE_MAC_DEVICE);
-
- void setup() {
- pinMode(13, OUTPUT);
- Serial.begin(115200);
- }
- void loop() {
-
- do {
- digitalWrite(led, LOW);
- Serial.println("Testing connection to Da Vinci EEPROM CHIP\n");
- delay(100);
- digitalWrite(led, HIGH);
- } while(!unio.read_status(&sr));
-
- Serial.println("Da Vinci EEPROM found...");
- Serial.println("Reading the Davinci EEPROM Contents...");
- dump_eeprom(0,128);
- //dump_eeprom(116,4);
- //*
- //Read the serial number - added by Matt
- byte buf[20];
- memset(buf,0,20);
- status(unio.read(buf,SN,12));
- //Increment the serial number
- IncrementSerial(&buf[0], 0, 12);
-
- Serial.println("Updating EEPROM...");
- status(unio.simple_write((const byte *)mt,MATERIAL,1));
- status(unio.simple_write((const byte *)cr,COLOR,2));
- status(unio.simple_write((const byte *)x,TOTALLEN,4));
- status(unio.simple_write((const byte *)x,NEWLEN,4));
- status(unio.simple_write((const byte *)et,HEADTEMP,2)); // extruder temp
- status(unio.simple_write((const byte *)bt,BEDTEMP,2)); // bed temp
- //Write the serial number
- status(unio.simple_write((const byte *)buf,SN,12)); //Serial Number
- status(unio.simple_write((const byte *)x,LEN2,4));
- status(unio.simple_write((const byte *)ef,EOFM,4));
- status(unio.simple_write((const byte *)cc,SCODE,4));
- // same block from offset 0 is offset 64 bytes
- status(unio.simple_write((const byte *)mt,64 + MATERIAL,1));
- status(unio.simple_write((const byte *)cr,64 + COLOR,2));
- status(unio.simple_write((const byte *)x,64 + TOTALLEN,4));
- status(unio.simple_write((const byte *)x,64 + NEWLEN,4));
- status(unio.simple_write((const byte *)et,64 + HEADTEMP,2)); // extruder temp
- status(unio.simple_write((const byte *)bt,64 + BEDTEMP,2)); // bed temp
- //Write the serial number
- status(unio.simple_write((const byte *)buf,64 + SN,12)); //Serial Number
- status(unio.simple_write((const byte *)x,64 + LEN2,4));
- status(unio.simple_write((const byte *)ef,64 + EOFM,4));
- status(unio.simple_write((const byte *)cc,64 + SCODE,4));
- Serial.println("Dumping Content after modification...");
- dump_eeprom(0,128);
- // */
-
- digitalWrite(led, HIGH); // turn the LED on
- delay(10000); // wait for two seconds
- }
复制代码
|