├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── ardunio ├── bdsensor_mega328p │ ├── Panda_segmentBed_I2C.cpp │ ├── Panda_segmentBed_I2C.h │ └── bdsensor_mega328p.ino └── esp32_vscode │ ├── .gitignore │ ├── .vscode │ ├── extensions.json │ └── settings.json │ ├── README.md │ ├── platformio.ini │ └── src │ └── main.cpp ├── design ├── PCB_case.stl ├── coil_case.step ├── coil_case.stl ├── coil_case_without_coil.stl └── size.png ├── doc ├── AVRtools │ ├── avrdude-5.11-Patch7610-win32.zip │ └── avrdue_flash_win32.txt ├── images │ ├── 0220517153950.png │ ├── 110959.jpg │ ├── 135204.jpg │ ├── 135228.jpg │ ├── 21110408.jpg │ ├── 30142854.png │ ├── 516115055.jpg │ ├── Connection1.jpg │ ├── Ny1.jpg │ ├── Read.jpg │ ├── Shawn_1.png │ ├── back.jpg │ ├── connect_white.jpg │ ├── data.jpg │ ├── exp1_connect.jpg │ ├── flashC51.jpg │ ├── howwork.png │ ├── light0.jpg │ ├── mainp.jpg │ ├── mainp2.jpg │ ├── mainv.jpg │ ├── map.jpg │ ├── skrv1_4.jpg │ ├── startC.jpg │ ├── stcisp.jpg │ └── stm32flash.jpg └── klipper_example │ └── delta │ └── printer.cfg ├── hex ├── README.md ├── V1.1_STC │ ├── V1.1_BD20230608.hex │ └── V1_1BDsensor20240213.hex └── V1.3_STM32 │ └── V1.2stm32_20240211.hex ├── klipper ├── BD_sensor.c ├── BDsensor.py ├── README.md ├── install_BDsensor.sh ├── make_with_bdsensor.sh ├── uninstall.sh └── width_bdsensor.py └── marlin ├── BD_Config_Tool_Marlin.zip └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: yuemark # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## The Future of 3D printer Bed Leveling 2 | 3 | [BDsensor](https://www.pandapi3d.com/bdsensor) is the first distance sensor that can work with 3D printer and do fast bed leveling and adjust z axis in real time. 4 | it can measure the bed distance at any point in real time without moving the z axis up and down. 5 | 6 | Faster leveling, realtime compensation, high accuracy. 7 | 8 | 1. No need to do probe points before every print, it will be automatically compensated for based on actual distance in real time. 9 | 10 | 2. You can do bed mesh leveling like a normal proximity sensor but much faster with this BDsensor. 11 | 12 | 3. Easy manual bed level adjustment thanks to ability to display the live sensor distance measurement on your screen. 13 | 14 | Sensor type: inductive, eddy, can only measure the metal plate. 15 | 16 | Range: 4mm (for different metal the range should be different, the normal pei steel plate is 4mm, but aluminum is about 2mm) 17 | 18 | 19 | ### Hardware: 20 | * It can connect to most motherboards or GPIOs on the RaspberryPi 21 | * Easy to install: 22 | small and light; can be installed anywhere, even surrounding metal above 23 | * Support Can bus module 24 | * Support high temperature chamber(120C) with the long cable probe [BDsensorM](https://github.com/markniu/Bed_Distance_sensor/wiki/BDsensor-M). 25 | ### Hardware Version 26 | . | hardware | firmware/software 27 | --- | --- |--- 28 | 2022.6 | BDsensor VA, V1.0 | V1.0 29 | 2023.4 | BDsensor VB, V1.1, the connector was changed | V1.1, support self reboot 30 | 2023.11 | BDsensor VB, V1.3, Upgrade the MCU to STM32 | V1.2, for stm32 31 | 2024.2 | |V1.2c, [Support nozzle collision sensing](https://github.com/markniu/Bed_Distance_sensor/wiki/Collision-sensing) 32 | 2024.3 | BDsensorM V1.0 | V1.2c 33 | 2024.7 | BDsensorM V1.1 | V1.2c, [Pins order](https://github.com/markniu/Bed_Distance_sensor/issues/178#issuecomment-2319621934) are changed in EXP1 connector 34 | 2025.1 | | [Auto calibration](https://www.pandapi3d.com/post/new-feature-for-bdsensor) 35 | 36 | ### Software 37 | . | Marlin | Klipper 38 | --- | --- |--- 39 | Real Time leveling |:heavy_check_mark:| :heavy_check_mark: 40 | Fast bed mesh |:heavy_check_mark:| :heavy_check_mark: 41 | Fast bed mesh(No toolhead stop)|:heavy_check_mark: | :heavy_check_mark: 42 | Distance display |:heavy_check_mark: | :heavy_check_mark: 43 | Can bus toolhead|No | :heavy_check_mark: 44 | standby mode automatic while printing|:heavy_check_mark: | :heavy_check_mark: 45 | [KAMP](https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging) Adaptive Meshing & Purging |No | :heavy_check_mark: 46 | nozzle collision sensing|[Detail](https://github.com/markniu/Bed_Distance_sensor/wiki/Collision-sensing-for-Marlin):heavy_check_mark: | :heavy_check_mark: 47 | 48 | ### Benefit of Collision sensing 49 | 1. **Auto z offset calibration**. 50 | 2. **Overcome the temperature drift**. 51 | The temperature drift will only change the z_offset, it will rise or low the whole bed mesh, but does not change the bed mesh with this BDsensor. that means the bed mesh is the same even with [different temperature](https://www.pandapi3d.com/post/nozzle-collision-sensing-with-bdsensor). 52 | 3. Repeatability: **+/-0.005mm** 53 | 4. No external hardware and easy to adjust 54 | 55 | ### Benefit of version M: 56 | 57 | 1. For High temperature chamber up to [120C](https://github.com/markniu/Bed_Distance_sensor/wiki/BDsensor-M) 58 | 2. The lightest probe, 1.5g 59 | 60 | ### Document : [WiKi](https://github.com/markniu/Bed_Distance_sensor/wiki) 61 | 62 | [History](https://hackaday.io/project/185096-0006mm-distance-resolution-sensor-for-3d-printer) 63 | 64 | #### Mount STL: [BLtouch_Compatible](https://www.thingiverse.com/thing:6098131) | [VzBoT](https://discord.com/channels/829828765512106054/1163237892957671424) | [Stealthburner Voron](https://www.printables.com/model/831679-lazy-bd-sensor-adapter-for-stealthburner-voron) 65 | 66 | ### Support 67 | https://www.facebook.com/groups/380795976169477 68 | 69 | 70 | #### Where to buy: 71 | [pandapi3d.com](https://www.pandapi3d.com) , [elecrow](https://www.elecrow.com/bd-sensor.html) , [淘宝店](https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-14344044600.5.60a16ff77NRBL5&id=684572042388) 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ardunio/bdsensor_mega328p/Panda_segmentBed_I2C.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Panda_segmentBed_I2C.h" 3 | 4 | int delay_time=100; 5 | //bool i2c_write(unsigned char value); 6 | //void i2c_stop(void); 7 | 8 | //#define setLow(pin) {if (_pullup) digitalWrite(pin, LOW); pinMode(pin, OUTPUT);} 9 | void I2C_SegmentBED::setLow(unsigned char pin) { 10 | noInterrupts(); 11 | pinMode(pin, OUTPUT); 12 | // if (_pullup) 13 | digitalWrite(pin, LOW); 14 | 15 | 16 | interrupts(); 17 | } 18 | 19 | //#define setHigh(pin) {if (_pullup) pinMode(pin, INPUT_PULLUP); else pinMode(pin, INPUT);} 20 | //#define i2c_start(addr) {setLow(I2C_BED_SDA);delayMicroseconds(delay_time); setLow(I2C_BED_SCL);return i2c_write(addr);} 21 | //#define i2c_stop() {setLow(I2C_BED_SDA); delayMicroseconds(delay_time); setHigh(I2C_BED_SCL); delayMicroseconds(delay_time); setHigh(I2C_BED_SDA);delayMicroseconds(delay_time);} 22 | 23 | 24 | void I2C_SegmentBED::setHigh(unsigned char pin) { 25 | // digitalWrite(pin,1); 26 | // return; 27 | noInterrupts(); 28 | //if (_pullup) 29 | pinMode(pin, INPUT_PULLUP); 30 | // else 31 | // pinMode(pin, INPUT); 32 | 33 | interrupts(); 34 | } 35 | int I2C_SegmentBED::i2c_init(unsigned char _sda,unsigned char _scl,unsigned char _addr,int delay_m) { 36 | I2C_BED_SDA=_sda; 37 | I2C_BED_SCL =_scl; 38 | I2C_7BITADDR = _addr; 39 | if(delay_m>0) 40 | delay_time=delay_m; 41 | pinMode(I2C_BED_SDA, OUTPUT); 42 | pinMode(I2C_BED_SCL, OUTPUT); 43 | digitalWrite(I2C_BED_SDA, LOW); 44 | digitalWrite(I2C_BED_SCL, LOW); 45 | if (digitalRead(I2C_BED_SDA) == HIGH || digitalRead(I2C_BED_SCL) == HIGH) return -1; 46 | setHigh(I2C_BED_SDA); 47 | setHigh(I2C_BED_SCL); 48 | if (digitalRead(I2C_BED_SDA) == LOW || digitalRead(I2C_BED_SCL) == LOW) return -2; 49 | return 1; 50 | } 51 | 52 | // Start transfer function: is the 8-bit I2C address (including the R/W 53 | // bit). 54 | // Return: true if the slave replies with an "acknowledge", false otherwise 55 | 56 | bool I2C_SegmentBED::i2c_start(unsigned char addr) { 57 | setLow(I2C_BED_SDA); 58 | delayMicroseconds(delay_time); 59 | setLow(I2C_BED_SCL); 60 | return i2c_write(addr); 61 | } 62 | 63 | // Try to start transfer until an ACK is returned 64 | /* i2c_start_wait(unsigned char addr) { 65 | long retry = I2C_MAXWAIT; 66 | while (!i2c_start(addr)) { 67 | i2c_stop(); 68 | if (--retry == 0) return false; 69 | } 70 | return true; 71 | } 72 | */ 73 | // Repeated start function: After having claimed the bus with a start condition, 74 | // you can address another or the same chip again without an intervening 75 | // stop condition. 76 | // Return: true if the slave replies with an "acknowledge", false otherwise 77 | bool I2C_SegmentBED::i2c_rep_start(unsigned char addr) { 78 | setHigh(I2C_BED_SDA); 79 | setHigh(I2C_BED_SCL); 80 | delayMicroseconds(delay_time); 81 | return i2c_start(addr); 82 | } 83 | 84 | // Issue a stop condition, freeing the bus. 85 | 86 | void I2C_SegmentBED::i2c_stop(void) { 87 | setLow(I2C_BED_SDA); 88 | delayMicroseconds(delay_time); 89 | setHigh(I2C_BED_SCL); 90 | delayMicroseconds(delay_time); 91 | setHigh(I2C_BED_SDA); 92 | delayMicroseconds(delay_time); 93 | } 94 | 95 | // Write one byte to the slave chip that had been addressed 96 | // by the previous start call. is the byte to be sent. 97 | // Return: true if the slave replies with an "acknowledge", false otherwise 98 | bool I2C_SegmentBED::i2c_write(unsigned char value) { 99 | for (unsigned char curr = 0X80; curr != 0; curr >>= 1) { 100 | if (curr & value) {setHigh(I2C_BED_SDA);} else setLow(I2C_BED_SDA); 101 | setHigh(I2C_BED_SCL); 102 | delayMicroseconds(delay_time); 103 | setLow(I2C_BED_SCL); 104 | delayMicroseconds(delay_time); 105 | } 106 | // get Ack or Nak 107 | setHigh(I2C_BED_SDA); 108 | setHigh(I2C_BED_SCL); 109 | delayMicroseconds(delay_time); 110 | unsigned char ack = digitalRead(I2C_BED_SDA); 111 | setLow(I2C_BED_SCL); 112 | delayMicroseconds(delay_time); 113 | setLow(I2C_BED_SDA); 114 | return ack == 0; 115 | } 116 | 117 | // Read one byte. If is true, we send a NAK after having received 118 | // the byte in order to terminate the read sequence. 119 | unsigned char I2C_SegmentBED::i2c_read(bool last) { 120 | unsigned char b = 0; 121 | setHigh(I2C_BED_SDA); 122 | for (unsigned char i = 0; i < 8; i++) { 123 | b <<= 1; 124 | delayMicroseconds(delay_time); 125 | setHigh(I2C_BED_SCL); 126 | delayMicroseconds(delay_time); 127 | if (digitalRead(I2C_BED_SDA)) b |= 1; 128 | setLow(I2C_BED_SCL); 129 | } 130 | if (last) {setHigh(I2C_BED_SDA);} else setLow(I2C_BED_SDA); 131 | setHigh(I2C_BED_SCL); 132 | delayMicroseconds(delay_time); 133 | setLow(I2C_BED_SCL); 134 | delayMicroseconds(delay_time); 135 | setLow(I2C_BED_SDA); 136 | return b; 137 | } 138 | 139 | 140 | void I2C_SegmentBED::I2C_send_str(char *dat_r,char send_now) 141 | { 142 | int i=0; 143 | i2c_stop(); 144 | // static unsigned long timeout = millis() + 100; 145 | // if(((long)(millis() - timeout) > 0L)||(send_now)) 146 | { 147 | // timeout=millis() + 100; 148 | if(i2c_start((I2C_7BITADDR<<1)|I2C_WRITE)) 149 | { 150 | i2c_write(0x00); 151 | // i2c_rep_start((I2C_7BITADDR<<1)|I2C_WRITE); 152 | while(*dat_r) 153 | i2c_write(*dat_r++); 154 | } 155 | i2c_stop(); 156 | } 157 | 158 | 159 | } 160 | 161 | void I2C_SegmentBED::I2C_read_str(char *dat_r,int addr) 162 | { 163 | i2c_stop(); 164 | if(i2c_start((I2C_7BITADDR<<1)|I2C_WRITE)) 165 | { 166 | int i =0; 167 | i2c_write(addr); 168 | i2c_rep_start((I2C_7BITADDR<<1)|I2C_READ); 169 | while(i<=50) // the max length is 50 bytes 170 | { 171 | dat_r[i]= i2c_read(false); 172 | if(dat_r[i]==0) 173 | break; 174 | i++; 175 | } 176 | i2c_read(true); 177 | 178 | } 179 | i2c_stop(); 180 | } 181 | //////////////////////////// 182 | 183 | unsigned short I2C_SegmentBED::BD_Add_OddEven(unsigned short byte) 184 | { 185 | unsigned char i; 186 | unsigned char n; 187 | unsigned short r; 188 | n =0; 189 | for(i=0;i<10;i++) 190 | { 191 | if(((byte >>i)&0x01) == 0x01) 192 | { 193 | n++; 194 | } 195 | } 196 | if((n&0x01) == 0x01) 197 | { 198 | r = byte | 0x400; 199 | } 200 | else 201 | { 202 | r = byte | 0x00; 203 | } 204 | return r; 205 | } 206 | 207 | #define BYTE_CHECK_OK 0x01 208 | #define BYTE_CHECK_ERR 0x00 209 | /****************************************************************************************** 210 | 211 | ********************************************************************************************/ 212 | unsigned short I2C_SegmentBED::BD_Check_OddEven(unsigned short byte) 213 | { 214 | unsigned char i; 215 | unsigned char n; 216 | unsigned char r; 217 | n =0; 218 | for(i=0;i<10;i++) 219 | { 220 | if(((byte >>i)&0x01) == 0x01) 221 | { 222 | n++; 223 | } 224 | } 225 | if((byte>>10) == (n&0x01)) 226 | { 227 | r = BYTE_CHECK_OK; 228 | } 229 | else 230 | { 231 | r = BYTE_CHECK_ERR; 232 | } 233 | return r; 234 | } 235 | 236 | void I2C_SegmentBED::BD_setLow(unsigned char pin) { 237 | noInterrupts(); 238 | pinMode(pin, OUTPUT); 239 | digitalWrite(pin, LOW); 240 | interrupts(); 241 | } 242 | 243 | void I2C_SegmentBED::BD_setHigh(unsigned char pin) { 244 | BD_set_force_High(pin); 245 | return; 246 | noInterrupts(); 247 | pinMode(pin, INPUT_PULLUP); 248 | interrupts(); 249 | } 250 | 251 | void I2C_SegmentBED::BD_set_force_High(unsigned char pin) { 252 | noInterrupts(); 253 | pinMode(pin, OUTPUT); 254 | digitalWrite(pin, HIGH); 255 | interrupts(); 256 | } 257 | 258 | 259 | bool I2C_SegmentBED::BD_I2C_start(void) 260 | { 261 | BD_setHigh(I2C_BED_SCL); 262 | BD_setHigh(I2C_BED_SDA); 263 | delayMicroseconds(delay_time); 264 | BD_setLow(I2C_BED_SDA); 265 | delayMicroseconds(delay_time); 266 | BD_setLow(I2C_BED_SCL); 267 | delayMicroseconds(delay_time); 268 | return true; 269 | } 270 | void I2C_SegmentBED::BD_i2c_stop(void) { 271 | delayMicroseconds(delay_time); 272 | BD_setLow(I2C_BED_SDA); 273 | delayMicroseconds(delay_time); 274 | BD_setHigh(I2C_BED_SCL); 275 | delayMicroseconds(delay_time); 276 | BD_setHigh(I2C_BED_SDA); 277 | delayMicroseconds(delay_time); 278 | } 279 | 280 | unsigned short I2C_SegmentBED::BD_i2c_read(void) 281 | { 282 | 283 | BD_I2C_start(); 284 | //// read 285 | BD_setHigh(I2C_BED_SDA); 286 | BD_setHigh(I2C_BED_SCL); 287 | delayMicroseconds(delay_time); 288 | BD_setLow(I2C_BED_SCL); 289 | /// 290 | delayMicroseconds(delay_time); 291 | unsigned short b = 0; 292 | //BD_setHigh(I2C_BED_SDA); 293 | noInterrupts(); 294 | pinMode(I2C_BED_SDA, INPUT_PULLUP); 295 | interrupts(); 296 | for (unsigned char i = 0; i <= 10; i++) { 297 | b <<= 1; 298 | delayMicroseconds(delay_time); 299 | BD_setHigh(I2C_BED_SCL); 300 | delayMicroseconds(delay_time); 301 | if (digitalRead(I2C_BED_SDA)) b |= 1; 302 | delayMicroseconds(delay_time); 303 | BD_setLow(I2C_BED_SCL); 304 | } 305 | BD_i2c_stop(); 306 | return b; 307 | 308 | } 309 | 310 | void I2C_SegmentBED::BD_i2c_write(unsigned int addr) 311 | { 312 | 313 | BD_I2C_start(); 314 | //// write 315 | BD_setLow(I2C_BED_SDA); 316 | BD_set_force_High(I2C_BED_SCL); 317 | delayMicroseconds(delay_time); 318 | BD_setLow(I2C_BED_SCL); 319 | addr=BD_Add_OddEven(addr); 320 | ///write address 321 | delayMicroseconds(delay_time); 322 | for (int i=10; i >=0; i--) 323 | { 324 | if ((addr>>i)&0x01) {BD_set_force_High(I2C_BED_SDA);} else BD_setLow(I2C_BED_SDA); 325 | //if (addr &curr) {set_force_High(I2C_BED_SDA);} else setLow(I2C_BED_SDA); 326 | BD_set_force_High(I2C_BED_SCL); 327 | delayMicroseconds(delay_time); 328 | BD_setLow(I2C_BED_SCL); 329 | delayMicroseconds(delay_time); 330 | } 331 | //////////// 332 | BD_i2c_stop(); 333 | 334 | 335 | } 336 | -------------------------------------------------------------------------------- /ardunio/bdsensor_mega328p/Panda_segmentBed_I2C.h: -------------------------------------------------------------------------------- 1 | // 2 | #ifndef Panda_segmentBed_I2C_h 3 | #define Panda_segmentBed_I2C_h 4 | 5 | #define I2C_READ 1 6 | #define I2C_WRITE 0 7 | //#define DELAY 100 // usec delay 8 | #define BUFFER_LENGTH 32 9 | #define I2C_MAXWAIT 5000 10 | //#define I2C_7BITADDR 0x3C// DS1307 11 | #define MEMLOC 0x0A 12 | #define ADDRLEN 1 13 | 14 | class I2C_SegmentBED{ 15 | public: 16 | int i2c_init(unsigned char _sda,unsigned char _scl,unsigned char _addr,int delay_m); 17 | void I2C_read_str(char *dat_r,int addr); 18 | void I2C_send_str(char *dat_r,char send_now); 19 | ////////////////////// 20 | void BD_i2c_write(unsigned int addr); 21 | unsigned short BD_i2c_read(void); 22 | void BD_i2c_stop(void); 23 | bool BD_I2C_start(void); 24 | unsigned short BD_Check_OddEven(unsigned short byte); 25 | unsigned short BD_Add_OddEven(unsigned short byte); 26 | 27 | private: 28 | unsigned char I2C_BED_SDA,I2C_BED_SCL; 29 | unsigned char I2C_7BITADDR=0x3C; 30 | 31 | unsigned char _pullup =true ; 32 | void setLow(unsigned char pin) ; 33 | void setHigh(unsigned char pin); 34 | bool i2c_start(unsigned char addr) ; 35 | bool i2c_rep_start(unsigned char addr); 36 | void i2c_stop(void); 37 | bool i2c_write(unsigned char value); 38 | unsigned char i2c_read(bool last); 39 | ////////////////////// 40 | void BD_setLow(unsigned char pin); 41 | void BD_setHigh(unsigned char pin) ; 42 | void BD_set_force_High(unsigned char pin); 43 | 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ardunio/bdsensor_mega328p/bdsensor_mega328p.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Panda_segmentBed_I2C.h" 4 | #ifdef U8X8_HAVE_HW_SPI 5 | #include 6 | #endif 7 | #ifdef U8X8_HAVE_HW_I2C 8 | #include 9 | #endif 10 | 11 | I2C_SegmentBED BD_SENSOR_I2C; 12 | #define I2C_BED_SDA 12 13 | #define I2C_BED_SCL 11 14 | #define DELAY 100 15 | #define MAX_BD_HEIGHT 6.9 16 | #define CMD_START_READ_CALIBRATE_DATA 1017 17 | #define CMD_END_READ_CALIBRATE_DATA 1018 18 | #define CMD_START_CALIBRATE 1019 19 | #define CMD_END_CALIBRATE 1021 20 | #define CMD_READ_VERSION 1016 21 | #define CMD_DISTANCD_RAWDATA_TYPE 1020 // switch output distance data type to raw data, default is mm (1 represent 0.01mm) 22 | 23 | char tmp_1[50]; 24 | unsigned int n=0,i=0; 25 | float Distance=0.0; 26 | 27 | U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); 28 | 29 | 30 | 31 | void dis_text(char *tmp_d,char x,char y) 32 | { 33 | 34 | u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font 35 | u8g2.drawStr(x,y,tmp_d); // write something to the internal memory 36 | u8g2.sendBuffer(); // transfer internal memory to the display 37 | 38 | } 39 | 40 | unsigned short read_one_data() 41 | { 42 | unsigned short tmp=0; 43 | tmp=BD_SENSOR_I2C.BD_i2c_read(); 44 | if(BD_SENSOR_I2C.BD_Check_OddEven(tmp)==0) 45 | //printf("CRC error!\n"); 46 | // sprintf(tmp_1,"CRC error"); 47 | tmp=1024; 48 | else 49 | { 50 | tmp=(tmp&0x3ff); 51 | // sprintf(tmp_1,"Distance:%.2f\n",Distance); 52 | //printf(tmp_1); 53 | } 54 | return tmp; 55 | } 56 | 57 | void read_version(char *txt) 58 | { 59 | int i=0; 60 | BD_SENSOR_I2C.BD_i2c_write(CMD_READ_VERSION); 61 | for(i=0;i<20;i++) 62 | txt[i]=read_one_data(); 63 | BD_SENSOR_I2C.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); 64 | } 65 | 66 | 67 | unsigned short read_raw_data(void) 68 | { 69 | unsigned short tm=0; 70 | BD_SENSOR_I2C.BD_i2c_write(CMD_DISTANCD_RAWDATA_TYPE); 71 | tm=read_one_data(); 72 | BD_SENSOR_I2C.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); 73 | return tm; 74 | } 75 | 76 | void setup(void) { 77 | u8g2.begin(); 78 | u8g2.clearBuffer(); // clear the internal memory 79 | BD_SENSOR_I2C.i2c_init(I2C_BED_SDA,I2C_BED_SCL,0x3C,20); 80 | BD_SENSOR_I2C.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); 81 | //read and display version 82 | sprintf(tmp_1,""); 83 | read_version(tmp_1+strlen(tmp_1)); 84 | dis_text(tmp_1,0,10); 85 | /// 86 | 87 | } 88 | 89 | void loop(void) { 90 | u8g2.clearBuffer(); 91 | u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font 92 | //u8g2.drawStr(x,y,tmp_d); // write something to the internal memory 93 | //u8g2.sendBuffer(); 94 | 95 | sprintf(tmp_1,""); 96 | read_version(tmp_1+strlen(tmp_1)); 97 | //dis_text(tmp_1,0,10); 98 | u8g2.drawStr(0,10,tmp_1); 99 | 100 | //delay(10); 101 | //read and display raw data 102 | n=read_raw_data(); 103 | sprintf(tmp_1,"%d ",n); 104 | //dis_text(tmp_1,0,30); 105 | 106 | // read and display distance,but need to calibrate first 107 | Distance=read_one_data()/100.0; 108 | sprintf(tmp_1+strlen(tmp_1),", "); 109 | dtostrf(Distance, 5, 2, tmp_1+strlen(tmp_1)); 110 | sprintf(tmp_1+strlen(tmp_1)," mm"); 111 | u8g2.drawStr(0,30,tmp_1); 112 | u8g2.sendBuffer(); 113 | //dis_text(tmp_1,0,30); 114 | 115 | } 116 | -------------------------------------------------------------------------------- /ardunio/esp32_vscode/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /ardunio/esp32_vscode/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /ardunio/esp32_vscode/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "system_error": "cpp", 4 | "array": "cpp", 5 | "functional": "cpp", 6 | "tuple": "cpp", 7 | "type_traits": "cpp", 8 | "utility": "cpp", 9 | "random": "cpp" 10 | } 11 | } -------------------------------------------------------------------------------- /ardunio/esp32_vscode/README.md: -------------------------------------------------------------------------------- 1 | 2 | Arduino testing code 3 | 4 | This is a simple arduino testing code. It read the distance data from BDsensor after initial the communication port. 5 | 6 | If you want to do more code by yourself for other application here is the protocol of data 7 | 8 | https://github.com/markniu/Bed_Distance_sensor/wiki/Data-Protocol 9 | 10 | -------------------------------------------------------------------------------- /ardunio/esp32_vscode/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32dev] 12 | platform = espressif32 13 | board = esp32dev 14 | framework = arduino 15 | lib_deps = 16 | markyue/Panda_SoftMasterI2C 17 | 18 | 19 | -------------------------------------------------------------------------------- /ardunio/esp32_vscode/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | I2C_SegmentBED BD_SENSOR_I2C; 4 | #define I2C_BED_SDA 2 5 | #define I2C_BED_SCL 15 6 | #define DELAY 100 7 | #define MAX_BD_HEIGHT 6.9 8 | #define CMD_START_READ_CALIBRATE_DATA 1017 9 | #define CMD_END_READ_CALIBRATE_DATA 1018 10 | #define CMD_START_CALIBRATE 1019 11 | #define CMD_END_CALIBRATE 1021 12 | #define CMD_READ_VERSION 1016 13 | 14 | char tmp_1[50]; 15 | unsigned int n=0,i=0; 16 | float Distance=0.0; 17 | void setup() { 18 | delay(500); 19 | BD_SENSOR_I2C.i2c_init(I2C_BED_SDA,I2C_BED_SCL,0x3C,10); 20 | Serial.begin(115200); 21 | n=0; 22 | } 23 | 24 | void loop() { 25 | unsigned short tmp=0; 26 | tmp=BD_SENSOR_I2C.BD_i2c_read(); 27 | if(BD_SENSOR_I2C.BD_Check_OddEven(tmp)==0) 28 | printf("CRC error!\n"); 29 | else 30 | { 31 | Distance=(tmp&0x3ff)/100.0; 32 | sprintf(tmp_1,"Distance:%.2f\n",Distance); 33 | printf(tmp_1); 34 | } 35 | delay(100); 36 | if((tmp&0x3ff)<1020) 37 | { 38 | /////Read Calibrate data 39 | if(n==10) 40 | { 41 | BD_SENSOR_I2C.BD_i2c_write(CMD_START_READ_CALIBRATE_DATA); 42 | delay(1000); 43 | printf("\nRead Calibrate data:"); 44 | for(i=0;i<60;i++) 45 | { 46 | tmp=BD_SENSOR_I2C.BD_i2c_read(); 47 | sprintf(tmp_1,"%d,%d,%d\n",i,tmp&0x3ff,BD_SENSOR_I2C.BD_Check_OddEven(tmp)); 48 | printf(tmp_1); 49 | delay(100); 50 | } 51 | printf("\n"); 52 | BD_SENSOR_I2C.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); 53 | 54 | 55 | } 56 | n++; 57 | } 58 | else 59 | { 60 | BD_SENSOR_I2C.BD_i2c_stop(); 61 | delay(500); 62 | BD_SENSOR_I2C.BD_i2c_stop(); 63 | } 64 | 65 | 66 | 67 | 68 | } -------------------------------------------------------------------------------- /design/PCB_case.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/design/PCB_case.stl -------------------------------------------------------------------------------- /design/coil_case.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/design/coil_case.stl -------------------------------------------------------------------------------- /design/coil_case_without_coil.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/design/coil_case_without_coil.stl -------------------------------------------------------------------------------- /design/size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/design/size.png -------------------------------------------------------------------------------- /doc/AVRtools/avrdude-5.11-Patch7610-win32.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/AVRtools/avrdude-5.11-Patch7610-win32.zip -------------------------------------------------------------------------------- /doc/AVRtools/avrdue_flash_win32.txt: -------------------------------------------------------------------------------- 1 | 2 | for example: 3 | avrdude -c wiring -P COM7 -b115200 -p atmega2560 -D -U flash:w:firmware_printer.hex:i -------------------------------------------------------------------------------- /doc/images/0220517153950.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/0220517153950.png -------------------------------------------------------------------------------- /doc/images/110959.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/110959.jpg -------------------------------------------------------------------------------- /doc/images/135204.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/135204.jpg -------------------------------------------------------------------------------- /doc/images/135228.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/135228.jpg -------------------------------------------------------------------------------- /doc/images/21110408.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/21110408.jpg -------------------------------------------------------------------------------- /doc/images/30142854.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/30142854.png -------------------------------------------------------------------------------- /doc/images/516115055.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/516115055.jpg -------------------------------------------------------------------------------- /doc/images/Connection1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/Connection1.jpg -------------------------------------------------------------------------------- /doc/images/Ny1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/Ny1.jpg -------------------------------------------------------------------------------- /doc/images/Read.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/Read.jpg -------------------------------------------------------------------------------- /doc/images/Shawn_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/Shawn_1.png -------------------------------------------------------------------------------- /doc/images/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/back.jpg -------------------------------------------------------------------------------- /doc/images/connect_white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/connect_white.jpg -------------------------------------------------------------------------------- /doc/images/data.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/data.jpg -------------------------------------------------------------------------------- /doc/images/exp1_connect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/exp1_connect.jpg -------------------------------------------------------------------------------- /doc/images/flashC51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/flashC51.jpg -------------------------------------------------------------------------------- /doc/images/howwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/howwork.png -------------------------------------------------------------------------------- /doc/images/light0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/light0.jpg -------------------------------------------------------------------------------- /doc/images/mainp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/mainp.jpg -------------------------------------------------------------------------------- /doc/images/mainp2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/mainp2.jpg -------------------------------------------------------------------------------- /doc/images/mainv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/mainv.jpg -------------------------------------------------------------------------------- /doc/images/map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/map.jpg -------------------------------------------------------------------------------- /doc/images/skrv1_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/skrv1_4.jpg -------------------------------------------------------------------------------- /doc/images/startC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/startC.jpg -------------------------------------------------------------------------------- /doc/images/stcisp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/stcisp.jpg -------------------------------------------------------------------------------- /doc/images/stm32flash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/doc/images/stm32flash.jpg -------------------------------------------------------------------------------- /doc/klipper_example/delta/printer.cfg: -------------------------------------------------------------------------------- 1 | # This file is an example config file for linear delta style printers. 2 | # One may copy and edit this file to configure a new delta printer. 3 | 4 | # DO NOT COPY THIS FILE WITHOUT CAREFULLY READING AND UPDATING IT 5 | # FIRST. Incorrectly configured parameters may cause damage. 6 | 7 | # See docs/Config_Reference.md for a description of parameters. 8 | [virtual_sdcard] 9 | path: ~/printer_data/gcodes 10 | 11 | [printer] 12 | kinematics: delta 13 | max_velocity: 300 14 | max_accel: 3000 15 | max_z_velocity: 150 16 | #delta_radius: 136 17 | 18 | [BDsensor] 19 | #sda_pin: PB1 # example of connecting to main board Creality V4.2.7 20 | #scl_pin: PB0 # example of connecting to main board Creality V4.2.7 21 | scl_pin:PB0 22 | sda_pin:PB1 23 | delay: 20 # 20us per pulse, this value should be >=20 24 | z_offset:0 # this `z_offset` must be set to 0. 25 | x_offset: 20 26 | y_offset: 0 27 | samples:1 28 | sample_retract_dist:2 29 | #no_stop_probe: # enable this for fast probe, the toolhead will not stop at the probe point. 30 | position_endstop: 0.5 # the Z axis will stop at this position (mm) while homing z, recommend value is 0.4~1.0 31 | speed:2 32 | 33 | [bed_mesh] 34 | speed: 50 35 | horizontal_move_z: 1.5 36 | mesh_radius: 85 37 | mesh_origin: 0, 0 38 | round_probe_count: 13 39 | algorithm:bicubic 40 | 41 | [delta_calibrate] 42 | radius:100 43 | horizontal_move_z: 5 44 | speed:100 45 | 46 | [stepper_a] 47 | step_pin: PB9 48 | dir_pin: !PC2 49 | enable_pin: !PC3 50 | microsteps: 16 51 | rotation_distance: 40 52 | endstop_pin: !PA5 53 | homing_speed: 50 54 | #position_endstop:241 55 | #arm_length: 261.0 56 | #angle: 211.942263 57 | 58 | [stepper_b] 59 | step_pin: PB7 60 | dir_pin: !PB8 61 | enable_pin: !PC3 62 | microsteps: 16 63 | rotation_distance: 40 64 | endstop_pin: !PA6 65 | 66 | [stepper_c] 67 | step_pin: PB5 68 | dir_pin: !PB6 69 | enable_pin: !PC3 70 | microsteps: 16 71 | rotation_distance: 40 72 | endstop_pin: !PA7 73 | 74 | [extruder] 75 | step_pin: PB3 76 | dir_pin: PB4 77 | enable_pin: !PC3 78 | microsteps: 16 79 | rotation_distance: 33.500 80 | nozzle_diameter: 0.400 81 | filament_diameter: 1.750 82 | heater_pin: PA1 83 | sensor_type: EPCOS 100K B57560G104F 84 | sensor_pin: PC5 85 | control: pid 86 | pid_Kp: 22.2 87 | pid_Ki: 0.1 88 | pid_Kd: 114 89 | min_temp: 0 90 | max_temp: 250 91 | max_power: 0.3 92 | 93 | #[fan] 94 | #pin: PA0 95 | 96 | [heater_fan fan1] 97 | pin: PA0 98 | 99 | [mcu] 100 | serial: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 101 | 102 | #*# <---------------------- SAVE_CONFIG ----------------------> 103 | #*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated. 104 | #*# 105 | #*# [printer] 106 | #*# delta_radius = 138.477847 107 | #*# 108 | #*# [stepper_a] 109 | #*# angle = 212.670115 110 | #*# arm_length = 261.000000 111 | #*# position_endstop = 239.326512 112 | #*# 113 | #*# [stepper_b] 114 | #*# angle = 331.740176 115 | #*# arm_length = 261.000000 116 | #*# position_endstop = 241.052320 117 | #*# 118 | #*# [stepper_c] 119 | #*# angle = 90.000000 120 | #*# arm_length = 261.000000 121 | #*# position_endstop = 238.118466 122 | #*# 123 | #*# [delta_calibrate] 124 | #*# height0 = 0.0 125 | #*# height0_pos = 19140.000,19263.000,19069.000 126 | #*# height1 = 0.0 127 | #*# height1_pos = 23890.600,23708.600,16164.600 128 | #*# height2 = 0.0 129 | #*# height2_pos = 18522.400,26807.400,18310.400 130 | #*# height3 = 0.0 131 | #*# height3_pos = 16414.800,23168.800,22889.800 132 | #*# height4 = 0.0 133 | #*# height4_pos = 18217.400,18497.400,24188.400 134 | #*# height5 = 0.0 135 | #*# height5_pos = 22146.000,16718.000,22221.000 136 | #*# height6 = 0.0 137 | #*# height6_pos = 25342.600,18364.600,18230.600 138 | -------------------------------------------------------------------------------- /hex/README.md: -------------------------------------------------------------------------------- 1 | How to download the firmware into bdsensor: 2 | 3 | [V1.3 STM32](https://github.com/markniu/Bed_Distance_sensor/wiki/Flash-BDsensor(stm32)-firmware) 4 | 5 | [V1.1_STC](https://github.com/markniu/Bed_Distance_sensor/wiki/Flash-BDsensor(V1.1)-firmware) 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hex/V1.1_STC/V1.1_BD20230608.hex: -------------------------------------------------------------------------------- 1 | :03000000020E905D 2 | :0C0E9000787FE4F6D8FD758171020ED762 3 | :101243004572617365200A0073617665696E672074 4 | :10125300746F20666C617368203D3D3D0A00202C4D 5 | :10126300256420002562643A25753B20004F2564E0 6 | :0B1273002C4625642C532562640A0001 7 | :100F820001670054009656312E312070616E646103 8 | :100F9200706933642E636F6D0A000165FF025B00A6 9 | :100FA20000026C0000026A000002630000026E0090 10 | :100FB2000002700000025F0000016600015700019C 11 | :100FC200560002610000025D03F702590000026848 12 | :020FD20000001D 13 | :0A14250000007F027E0FDEFEDFFCF8 14 | :01142F00229A 15 | :1013CD007C007D0A120C96AA06AB07121425EB1BA6 16 | :0813DD0070011A144A70F42299 17 | :04103B00AD07AC064B 18 | :10103F00E47851F618F67850E6FFC3940A7480945A 19 | :10104F0080501AAE04EDA807088005CEC313CE1347 20 | :10105F00D8F930E00378510678500680D97851E6F8 21 | :10106F0054016401700AEC440408F6ED08F6800B95 22 | :10107F00AE04AF057852A60608A6077852E6FE081A 23 | :02108F00E6FF7A 24 | :01109100223C 25 | :0410E500AD07AC06A1 26 | :1010E900E47851F618F67850E6FFC3940A748094B0 27 | :1010F90080501AAE04EDA807088005CEC313CE139D 28 | :10110900D8F930E00378510678500680D9EC1313EA 29 | :10111900543FFF7851E65401B5070508760180046C 30 | :0A112900E47852F67852E6FF7E00EB 31 | :011133002299 32 | :08060F009000AAEEF0A3EFF049 33 | :10061700E4782EF608F608F608F674FF782CF60844 34 | :10062700F6E47832F608F67832E6FE08E6FFC39479 35 | :100637004BEE940040030206DEEF25E0FFEE33FEAB 36 | :1006470074002FF58274003EF583E0FEA3E0FFF40B 37 | :100657007002EEF460769000AAE0FAA3E0FBD39F65 38 | :10066700EA9E4023E625E0FF18E633FE74002FF5E7 39 | :100677008274003EF583E0FEA3E0FFC3EB9F782F73 40 | :10068700F6EA9E18F680217833E625E0FF18E63370 41 | :10069700FE74002FF58274003EF583E0FEA3E0C3ED 42 | :1006A7009B782FF6EE9A18F6782EE6FE08E6FFD32B 43 | :1006B700782DE69F18E69E4013A60608A60778320F 44 | :1006C700E6FE08E6FF7830A60608A607783306E6B2 45 | :1006D7001870010602062EED6401600302084278D5 46 | :1006E70031E625E0FF18E633FE74002FF58274002B 47 | :1006F7003EF583E0FAA3E0FB9000AAE0FEA3E0FF4B 48 | :10070700D39BEE9A4078EF9BFFEE9AFE7C007D0A22 49 | :10071700120C96782CA60608A6077831E625E0FF86 50 | :1007270018E633FE74022FF58274003EF583E0FE6F 51 | :10073700A3E0C39BFFEE9AFE120C96120CA8782E2C 52 | :10074700EEF608EFF6D39400EE9400402E18E6FC80 53 | :1007570008E6FD782CE6FE08E6FF120CA8AA06AB11 54 | :10076700077830E6FE08E6FF7C007D0A120C96EF5C 55 | :100777002B7831F6EE3A18F602084202082D783047 56 | :10078700E6FE08E6FFC39401EE9400500302084218 57 | :10079700EF25E0FFEE33FE74002FF58274003EF57F 58 | :1007A70083E0FAA3E0FB9000AAE0FEA3E0FFC3EB1F 59 | :1007B7009FFFEA9EFE7C007D0A120C96782CA60607 60 | :1007C70008A6077831E625E0FF18E633FE74FE2F0A 61 | :1007D700F58274FF3EF583E0FEA3E0FFC3EB9FFFC6 62 | :1007E700EA9EFE120C96120CA8782EEEF608EFF68B 63 | :1007F700D39400EE9400402E18E6FC08E6FD782C12 64 | :10080700E6FE08E6FF120CA8AA06AB077830E6FE5C 65 | :1008170008E6FF7C007D0A120C96C3EF9B7831F641 66 | :10082700EE9A18F680157830E6FE08E6FF7C007D24 67 | :100837000A120C967830A60608A607D37831E694F4 68 | :10084700FF18E69403400576030876FE7830E6FE47 69 | :0308570008E6FFB1 70 | :01085A00227B 71 | :0300030002038B6A 72 | :10038B00C0E0C083C082C0D075D000C000C001C027 73 | :10039B0002C003C004C005C006C007787106E6188A 74 | :1003AB007001067865E61460391470030204941426 75 | :1003BB0070030204D91470030205CE1470030205F6 76 | :1003CB00F0240560030205F620B20C20B309786512 77 | :1003DB007601786102048C787106E61870010602CA 78 | :1003EB0005F620B2030205F620B30302047F7865FD 79 | :1003FB00760208E6F9FB7A007004786E8008EB64ED 80 | :10040B00014A7013786AE6FE08E6FF12103B785F2C 81 | :10041B00A60608A6078068E9FFC39402748094803F 82 | :10042B00401AEF944D748094805011E925E024FC20 83 | :10043B00F582E434FFF583E0FEA38020E9FF7E0024 84 | :10044B00C3944D748094804036EF94617480948093 85 | :10045B00502D744929F582E43400F583E0FF785F71 86 | :10046B00EEF608EFF612103B785FA60608A60778A3 87 | :10047B006606800B78657603785B760008760078E5 88 | :10048B006C76000876000205F630B2030205F678AA 89 | :10049B006CE6FE08E6FFD3940AEE9400400B187648 90 | :1004AB000008760078700205E5C3740A9FFF785F39 91 | :1004BB00E6FE08E6A807088005CEC313CE13D8F9CD 92 | :1004CB001392B3786D06E6187001060205F620B29A 93 | :1004DB00030205F630B323786DE6FFC3740A9FFF62 94 | :1004EB007E007401A807088005C333CE33CED8F93C 95 | :1004FB00FFEE785B46F6EF0846F6786D06E6187069 96 | :10050B000106D3786DE6940A18E6940050030205B1 97 | :10051B00F6760008760078657605C2A8D2AAD2B323 98 | :10052B00785BE6FE08E6FF1210E5EF4E700302055E 99 | :10053B00F6785BE65403F6E6FE08E6FFC3944BEE53 100 | :10054B0094005020786AE6FC08E6FDEF25E0FFEE0C 101 | :10055B0033FE74002FF58274003EF583ECF0A3EDAF 102 | :10056B00F00205F6785BE6FE08E6FFBE0309BFFC6A 103 | :10057B0006786676018074BE0309BFFB0678577652 104 | :10058B00018068BE0309BFF8067866764D805CBEB5 105 | :10059B000309BFFD06785776028050BE0309BFF9E9 106 | :1005AB0006786676028044BE0309BFFA0678667643 107 | :1005BB00008038EF64FE7003EE6403702E7857767C 108 | :1005CB0004802820B225786D06E618700106D378D2 109 | :1005DB006DE6940918E694004011760008760078D1 110 | :1005EB006576058006C2A8D2AAD2B3D007D006D0B2 111 | :1005FB0005D004D003D002D001D000D0D0D082D00F 112 | :04060B0083D0E03286 113 | :0300130002117E59 114 | :10117E00C0E0C0D075D000C000C2A87865E604609B 115 | :10118E000314701520B31230B20F78657600786CA8 116 | :10119E007600087600C2AAD2A830B31430B2117805 117 | :1011AE006576FFC2A8D2AAD2B37870760008760010 118 | :0711BE00D000D0D0D0E032D8 119 | :071092007823E6FE08E6FFEB 120 | :04109900AB07AA06F1 121 | :10109D009000AA7411F0E4FDD294D295C294C29539 122 | :1010AD00EAC313139293D295C295EA139293D295F4 123 | :1010BD00C295AE02EBA805088005C333CE33CED85A 124 | :1010CD00F930E704D2938002C2930DD295EDC3940B 125 | :0710DD00087480948040D9E3 126 | :0110E40022E9 127 | :100F1C007865E6FF3395E0FEC364809480400A78E0 128 | :100F2C007106E6187009068006E47870F608F6BEBD 129 | :100F3C00FF0DBFFF0A786206E6187009068006E40A 130 | :100F4C007861F608F6D37871E6948818E694135015 131 | :100F5C000E7857E6FF3395E0FEEF64044E7016E40E 132 | :100F6C007857F67870F608F6786576FFC2A8D2AA9C 133 | :060F7C00D2B312000022B6 134 | :1013E500438E40E4F589758DCC758BCCD28ED2AB0E 135 | :0313F500D2AF2252 136 | :100D8600E4782CF6786906E618700106D37869E6E9 137 | :100D9600948818E69413401D785DE6FE08E6FF7811 138 | :100DA6006AEEF6FE08EFF6FF786EA60608A607E4DA 139 | :100DB6007868F608F6120F1C7857E6FF3395E0FEC2 140 | :100DC600EF64024E701876037BFF7A127943120F96 141 | :100DD600E1E4FFFE12135F7F647E000213CD7857B5 142 | :100DE600E6FF3395E0FEEF64034E706AF67BFF7A0A 143 | :100DF60012794B120FE1E4782CF6782CE6FFC394B7 144 | :100E06004B748094804003020E8FEF75F002A4FFAE 145 | :100E1600AEF02400F974003EFA7B019000AFE4F0D6 146 | :100E2600A37402F01212047BFF7A127961782CE621 147 | :100E360025E02400F582E43400F583E0FFA3E0908A 148 | :100E460000ADCFF0A3EFF0120FE17F017E00121389 149 | :100E5600CD782C0680A47857E6FF3395E0FEEF6444 150 | :100E6600014E7025F6782CF6782CE6FFC3944B7469 151 | :100E76008094805014EF25E02400F582E43400F5D8 152 | :090E86008374FFF0A3F00680DF85 153 | :010E8F002240 154 | :10085B00E47822F608F608F608F608F6782BF61276 155 | :10086B00137FD2AFC288C2A8C28A1213E5D2AAC222 156 | :10087B0090C2917F647E001213CDE47822F6782229 157 | :10088B00E6FF3395E0FEC3EF944BEE64809480500B 158 | :10089B005CEF25E0FFEE33FEC006C00774002FF9B6 159 | :1008AB0074003EFA7B019000AFE4F0A37402F0D029 160 | :1008BB0007D0061211C57BFF7A1279677822E6FF03 161 | :1008CB009000ADF03395E0FEEF25E0FFEE33FE74C4 162 | :1008DB00002FF58274003EF583E0FFA3E09000AE9D 163 | :1008EB00CFF0A3EFF0120FE17822068091D291D2D4 164 | :1008FB00907B017A007996120FE17859E6FE08E6B3 165 | :10090B00FF7823A60608A607E4786AF608F6786E41 166 | :10091B00F608F6782B7601120D8620B7030209AA8A 167 | :10092B00120D86121092782BE6FF3395E0FE782499 168 | :10093B00EF26F618EE36F67859E6FE08E6FF782332 169 | :10094B00E6FC08E6FDD39FEC9E5006782B760180E3 170 | :10095B0012785DE6FE08E6FFC3ED9FEC9E400B7838 171 | :10096B002B76FF7823A60608A607E47822F67822D2 172 | :10097B00E6FF3395E0FEC3EF940AEE64809480505B 173 | :10098B000912142530B7030680E420B78D7823E6CF 174 | :10099B00FE08E6FF786AA60608A607782B760130D4 175 | :1009AB00B703020922120D86121092782BE6FF3341 176 | :1009BB0095E0FE7824EF26F618EE36F67859E6FE2B 177 | :1009CB0008E6FF7823E6FC08E6FDD39FEC9E500675 178 | :1009DB00782B76018012785DE6FE08E6FFC3ED9F6B 179 | :1009EB00EC9E400B782B76FF7823A60608A607E42F 180 | :1009FB007822F67822E6FF3395E0FEC3EF940AEEF9 181 | :100A0B0064809480500912142520B7030680E430CB 182 | :100A1B00B78DE47868F608F67823E6FE08E6FF085B 183 | :100A2B00A60608A60708E6FE08E6786B667003EED6 184 | :100A3B00186670107829E6FE08E67826667003EED5 185 | :100A4B0018666050786AE6FE08E6FF7827A6060867 186 | :100A5B00A6077825E6FC08E6FD7829A60408A60576 187 | :100A6B007D0112060F786EA60608A6077BFF7A1289 188 | :100A7B007970786AE6FF08E69000ADCFF0A3EFF04F 189 | :100A8B007825E6FF08E6A3CFF0A3EFF07865E6A3A1 190 | :0B0A9B00F0120FE1782B76FF02092219 191 | :0C0FD400011000010F00010D00010E00D3 192 | :10137F00759850438E01438E0475D7BF75D6FF43C2 193 | :0B138F008E10D2ACD29CC29FD29E22D6 194 | :0B1419003098FDC298781DA699E6FFF0 195 | :0114240022A5 196 | :081430008F993099FDC2992249 197 | :1013F800120C6BFF600C121430740129F9E43AFAEC 198 | :0314080080EE2251 199 | :03002300020AA628 200 | :100AA600C0E0C0F0C083C082C0D075D000C000C016 201 | :100AB60001C002C003C004C005C006C007209803D9 202 | :100AC600020C4BC298900103E0FBA3E0FAA3E0F905 203 | :100AD600E599120C84900103E0FBA3E0FAA3E0F988 204 | :0A0AE600120C6B643B6003020C224B 205 | :100AF0007855F67811E6062413F876007812760217 206 | :100B0000785476007854E6FFC37811964003020CBF 207 | :100B10001974132FF8E6FE6452600DEE644160080C 208 | :100B2000EE644C6003020C1374142FF8E6FEB45606 209 | :100B300007780F7602020C1974152FF8E6FFFD33C3 210 | :100B400095E0FCC3ED9430EC648094804025EEFD8C 211 | :100B50003395E0FCC3ED9430EC64809480401478CD 212 | :100B600054E62414F8E624D075F00AA4FEEF24D04D 213 | :100B70002E801B7854E62414F8E6FFFD3395E0FC44 214 | :100B8000C3ED9430EC648094804013EF24D0FF9048 215 | :100B90000103E0FBA3E0FAA3E0F9EF120C8490015B 216 | :100BA00003E0FBA3E0FAA3E0F9120C6BD3946474A6 217 | :100BB0008094805064C374809480405D7854E624AF 218 | :100BC00013F8E6FFB45216780F7601120C6BFED3C1 219 | :100BD000940074809480404108A606803CEFB441A4 220 | :100BE0000C780F7601120C6B780DF6802C7854E699 221 | :100BF0002413F8E6B44C22780F7601120C6BFF7EBA 222 | :100C00000064017005187601800FEF4E700B780EAE 223 | :100C1000F68006785406020B0478127600187600E7 224 | :100C20008029900103E0FBA3E0FAA3E0F9120C6B2A 225 | :100C3000FF7811E6062413F8A6077812760118E665 226 | :100C4000D3940A7480948040027600309902C2994D 227 | :100C5000D007D006D005D004D003D002D001D000F8 228 | :0B0C6000D0D0D082D083D0F0D0E032A2 229 | :0B0FE1009000AAEBF0A3EAF0A3E9F0F7 230 | :100FEC00782D76010876000876AD9000AAE0F9A37A 231 | :100FFC00E0FAA3E09000D5C9F0A3EAF0A3E9F078F9 232 | :10100C002D860308E6FA08E6F9A3EBF0A3EAF0A3B1 233 | :10101C00E9F07B007A0079301211347B007A007988 234 | :0E102C00301213F8782DA6030876000876001F 235 | :01103A002293 236 | :02143F00002289 237 | :07143800D29300D2940022C0 238 | :0D000600D29400D29312143FC29302143F13 239 | :0D001600C29300D29412143FD29302143F03 240 | :1013B400C29400300904C2938002D29300D29412E2 241 | :0913C400143FC29400D2930022F0 242 | :08139A001200067FEA1212E9BD 243 | :1013A200D29412143F309305C29400C322C2940017 244 | :0213B200D32244 245 | :1012E900E4FEEEC39408748094805019C29400EF10 246 | :1012F90030E705D293008003C29300D29400EF2512 247 | :0B130900E0FF0E80DDC29400D29300D4 248 | :0113140022B6 249 | :10127E00C29400D29300E4FEEEFD7C00C394087489 250 | :10128E008094805025D29400EF3093054401FF8066 251 | :10129E000354FEFF00C29400C3ED9407EC648094E7 252 | :0A12AE00805004EF25E0FF0E80CE13 253 | :0112B8002213 254 | :10133C00AB0712139A400122AF031212E91213A247 255 | :10134C00400122AF051212E91213A2400122120031 256 | :03135C0016D32283 257 | :0212B900AD077F 258 | :1012BB0012139A40037F0022AF051212E9C20912E2 259 | :1012CB0013B41200067FEB1212E91213A240037F34 260 | :0D12DB00002212127EC2091213B412001676 261 | :0112E80022E3 262 | :0E140B00E4F5C7F5C5F5C675C3FF75C4FF222D 263 | :1011C500AD07AC06C2AF75C78375C501ECF5C3AFF6 264 | :1011D500058FC475C65A75C6A500E5C2120C840DE7 265 | :1011E500BD00010C740129F9E43AFA9000AF74FFCF 266 | :0F11F500F5F0120CFD45F070D012140BD2AF22A2 267 | :10135F00AD07AC06C2AFECF5C3AF058FC475C7833D 268 | :10136F0075C50375C65A75C6A50012140BD2AF22E8 269 | :10120400AD07AC06C2AF75C78375C502ECF5C3AFB5 270 | :10121400058FC4120C6BF5C275C65A75C6A5000DB0 271 | :10122400BD00010C740129F9E43AFA9000AF74FF8F 272 | :0F123400F5F0120CFD45F070D012140BD2AF2262 273 | :100E9C0002085BE493A3F8E493A34003F68001F209 274 | :100EAC0008DFF48029E493A3F85407240CC8C33357 275 | :100EBC00C4540F4420C8834004F456800146F6DF26 276 | :100ECC00E4800B0102040810204080900F82E47E25 277 | :100EDC00019360BCA3FF543F30E509541FFEE4931B 278 | :100EEC00A360010ECF54C025E060A840B8E493A3E2 279 | :100EFC00FAE493A3F8E493A3C8C582C8CAC583CA0D 280 | :100F0C00F0A3C8C582C8CAC583CADFE9DEE780BEC4 281 | :010FE0000010 282 | :100C6B00BB010689828A83E0225002E722BBFE0287 283 | :090C7B00E32289828A83E49322BA 284 | :100C8400BB010689828A83F0225002F722BBFE014F 285 | :020C9400F32249 286 | :100C9600EF8DF0A4A8F0CF8CF0A428CE8DF0A42E72 287 | :020CA600FE222C 288 | :100CA800BC000BBE0029EF8DF084FFADF022E4CC30 289 | :100CB800F875F008EF2FFFEE33FEEC33FCEE9DECF9 290 | :100CC800984005FCEE9DFE0FD5F0E9E4CEFD22ED3F 291 | :100CD800F8F5F0EE8420D21CFEADF075F008EF2F89 292 | :100CE800FFED33FD4007985006D5F0F222C398FD7A 293 | :050CF8000FD5F0EA2217 294 | :100CFD00C5F0F8A3E028F0C5F0F8E5821582700282 295 | :060D0D001583E038F0221E 296 | :101134009000D5E0FFA3E0FEA3E0CF9000DEF0A393 297 | :10114400EEF0A3EFF09000D8E0CBF0A3E0CAF0A358 298 | :10115400E0C9F07F229000E1AD82AC83120C6B8D6C 299 | :10116400828C83F0A309E970010ADFEC9000D8E0D7 300 | :0A117400FBA3E0FAA3E0F902008BF0 301 | :10002600E50824DEF582E43400F583E00508229035 302 | :1000360000DB3007039000DEE475F001120D40028C 303 | :100046000C6B2000E97F2ED2008018EF540F24900D 304 | :10005600D43440D4FF30040BEF24BFB41A0050034D 305 | :100066002461FFE50960021509050CE50C7002051F 306 | :100076000B30070E9000DBE475F001120D40EF0225 307 | :100086000C840213157403D2078003E4C207F50833 308 | :100096009000DB120D57E4F509F50BF50CE5096048 309 | :1000A600077F2012006980F5750AFFC201C200C2EF 310 | :1000B60002C203C205C206C208120035FF700D3027 311 | :1000C60007057F0012007AAF0CAE0B22B4255FC283 312 | :1000D600D5C204120035FF24D0B40A00501A75F0B8 313 | :1000E6000A780930D50508B6FF0106C6A426F6200B 314 | :1000F600D5047002D20380D924CFB41A00EF50047D 315 | :10010600C2E5D20402027BD20180C6D20080C0D2F0 316 | :100116000280BCD2D580BAD20580B47F2012006995 317 | :100126002002077401B5090040F1120026FF1200F3 318 | :10013600690200A3D208D2068095120026FB12009F 319 | :1001460026FA120026F94A4B7006794C7A037BFF91 320 | :1001560020022EE509602A7E008E82758300120D2C 321 | :100166001360060EEE650A70F0C2D5EBC0E0EAC079 322 | :10017600E0E9C0E0EE1202C2D0E0F9D0E0FAD0E049 323 | :10018600FB120C6BFF60AAEBC0E0EAC0E0E9C0E03E 324 | :10019600120069D0E02401F9D0E03400FAD0E0FB87 325 | :1001A600E50A0460DCD50AD980877BFF7A0279BE2E 326 | :1001B600D202809C791080027908C206C2088008A3 327 | :1001C600D2D5790A8004790AC2D5E50A047002F507 328 | :1001D6000AE4FAFDFEFF120026FC7B08200113123A 329 | :1001E6000026FD7B1030000A120026FE120026FFB4 330 | :1001F6007B20EC3382D592D55013C3E43000069FA2 331 | :10020600FFE49EFEE42001039DFDE49CFCE4CBF8A4 332 | :10021600C201EC700CCFCECDCCE824F8F870F38098 333 | :1002260017C3EF33FFEE33FEED33FDEC33FCEB3358 334 | :10023600FB994002FB0FD8E9EB300105F8D0E0C48A 335 | :1002460048B201C0E00AEC4D4E4F78207B0070C2E8 336 | :10025600EAB50A0040BCC0E01202C4D0F0D0E020EB 337 | :100266000104C4C0E0C4B201C0F0120052D0F0D5FF 338 | :10027600F0EB0200A3120D6001405301BA580111C0 339 | :100286004C010D4201BE4F01C64401C64901264339 340 | :0802960001CC5501B04601B096 341 | :10029E004501B047036C5001152D01192E013C2B61 342 | :1002AE00011D23013A2003552A00D54800000134D0 343 | :1002BE003F3F3F00790AA2D5200314300509B9103B 344 | :1002CE00020404B9080104A2D5200602500104203C 345 | :1002DE0002689202B509005034C0E07F2030031945 346 | :1002EE007F30A20272067205500F12031BC202C2A9 347 | :1002FE0006C205C2087F30800F300503E9C0E01248 348 | :10030E000069300503D0E0F9D0E0B509CC3005170F 349 | :10031E007F30B9100C1200697F583004077F788047 350 | :10032E0003B908031200693002057F2D0200697FB0 351 | :10033E00202008F87F2B2006F322920280CF286E11 352 | :10034E00756C6C2900D2011200263001F8C20178BA 353 | :10035E000930D50108F60200D52D50434958120038 354 | :10036E00262403B405004001E49003679312005A5B 355 | :0D037E00743A12005AD2037509040201BA44 356 | :100D1300BB010CE58229F582E5833AF583E0225095 357 | :100D230006E92582F8E622BBFE06E92582F8E222DF 358 | :0D0D3300E58229F582E5833AF583E49322F9 359 | :100D4000F8E0FBA3A3E0F925F0F0E582158270023C 360 | :070D50001583E0FA38F022E0 361 | :090D5700EBF0A3EAF0A3E9F0229D 362 | :100D6000D083D082F8E4937012740193700DA3A322 363 | :100D700093F8740193F5828883E473740293686036 364 | :060D8000EFA3A3A380DF36 365 | :10131500EFB40A07740D121320740A309811A899B6 366 | :10132500B8130CC2983098FDA899C298B811F63038 367 | :0713350099FDC299F5992210 368 | :00000001FF 369 | -------------------------------------------------------------------------------- /hex/V1.1_STC/V1_1BDsensor20240213.hex: -------------------------------------------------------------------------------- 1 | :0300000002101CCF 2 | :0C101C00787FE4F6D8FD7581790210633E 3 | :101398006F7574004572617365200A007361766524 4 | :1013A800696E6720746F20666C617368203D3D3DEF 5 | :1013B8000A00202C256420002562643A25753B200C 6 | :1013C800002070726573732025642C25642C2564B5 7 | :0713D8000A004F25640A0022 8 | :10118C0002720000026E000002560000016B005457 9 | :10119C00009656312E316270616E646170693364F1 10 | :1011AC002E636F6D0A000169FF025BFFFF025F0097 11 | :1011BC00000274000002700000026700000276005A 12 | :1011CC00000278000002630000016A00015900016E 13 | :1011DC00580002650000026103F7025D0000026C1A 14 | :0211EC00000001 15 | :0A16040000007F027E0FDEFEDFFC17 16 | :01160E0022B9 17 | :1015AC007C007D0A120F2CAA06AB07121604EB1B4B 18 | :0815BC0070011A144A70F422B8 19 | :04125500AD07AC062F 20 | :10125900E47851F618F67850E6FFC3940A7480943E 21 | :1012690080501AAE04EDA807088005CEC313CE132B 22 | :10127900D8F930E00378510678500680D97851E6DC 23 | :1012890054016401700AEC440408F6ED08F6800B79 24 | :10129900AE04AF057852A60608A6077852E6FE08FE 25 | :0212A900E6FF5E 26 | :0112AB002220 27 | :0412FF00AD07AC0685 28 | :10130300E47851F618F67850E6FFC3940A74809493 29 | :1013130080501AAE04EDA807088005CEC313CE1380 30 | :10132300D8F930E00378510678500680D9EC1313CE 31 | :10133300543FFF7851E65401B50705087601800450 32 | :0A134300E47852F67852E6FF7E00CF 33 | :01134D00227D 34 | :080985009000AAEEF0A3EFF0D0 35 | :10098D00E4782EF608F608F608F674FF782CF608CB 36 | :10099D00F6E47832F608F67832E6FE08E6FFC39400 37 | :1009AD004BEE94004003020A54EF25E0FFEE33FEB8 38 | :1009BD0074002FF58274003EF583E0FEA3E0FFF492 39 | :1009CD007002EEF460769000AAE0FAA3E0FBD39FEC 40 | :1009DD00EA9E4023E625E0FF18E633FE74002FF56E 41 | :1009ED008274003EF583E0FEA3E0FFC3EB9F782FFA 42 | :1009FD00F6EA9E18F680217833E625E0FF18E633F7 43 | :100A0D00FE74002FF58274003EF583E0FEA3E0C373 44 | :100A1D009B782FF6EE9A18F6782EE6FE08E6FFD3B1 45 | :100A2D00782DE69F18E69E4013A60608A607783295 46 | :100A3D00E6FE08E6FF7830A60608A607783306E638 47 | :100A4D00187001060209A4ED64016003020BB87869 48 | :100A5D0031E625E0FF18E633FE74002FF5827400B1 49 | :100A6D003EF583E0FAA3E0FB9000AAE0FEA3E0FFD1 50 | :100A7D00D39BEE9A4078EF9BFFEE9AFE7C007D0AA9 51 | :100A8D00120F2C782CA60608A6077831E625E0FF74 52 | :100A9D0018E633FE74022FF58274003EF583E0FEF6 53 | :100AAD00A3E0C39BFFEE9AFE120F2C120F3E782E81 54 | :100ABD00EEF608EFF6D39400EE9400402E18E6FC07 55 | :100ACD0008E6FD782CE6FE08E6FF120F3EAA06ABFF 56 | :100ADD00077830E6FE08E6FF7C007D0A120F2CEF4A 57 | :100AED002B7831F6EE3A18F6020BB8020BA37830DC 58 | :100AFD00E6FE08E6FFC39401EE94005003020BB826 59 | :100B0D00EF25E0FFEE33FE74002FF58274003EF505 60 | :100B1D0083E0FAA3E0FB9000AAE0FEA3E0FFC3EBA5 61 | :100B2D009FFFEA9EFE7C007D0A120F2C782CA606F4 62 | :100B3D0008A6077831E625E0FF18E633FE74FE2F90 63 | :100B4D00F58274FF3EF583E0FEA3E0FFC3EB9FFF4C 64 | :100B5D00EA9EFE120F2C120F3E782EEEF608EFF6DF 65 | :100B6D00D39400EE9400402E18E6FC08E6FD782C98 66 | :100B7D00E6FE08E6FF120F3EAA06AB077830E6FE4A 67 | :100B8D0008E6FF7C007D0A120F2CC3EF9B7831F62F 68 | :100B9D00EE9A18F680157830E6FE08E6FF7C007DAB 69 | :100BAD000A120F2C7830A60608A607D37831E694E2 70 | :100BBD00FF18E69403400576030876FE7830E6FECE 71 | :030BCD0008E6FF38 72 | :010BD0002202 73 | :030003000206AC46 74 | :1006AC00C0E0C083C082C0D075D000C000C001C003 75 | :1006BC0002C003C004C005C006C007787906E6185E 76 | :1006CC007001067869E62402602324FEB40600401B 77 | :1006DC000302096C9006E7F8282873020714020736 78 | :1006EC002E0207D502081A02094402096620B20339 79 | :1006FC0002096C786976FF78787600087600785B6A 80 | :10070C0076FF0876FF02096620B20C20B3097869DF 81 | :10071C00760178650207CD787906E6187001060235 82 | :10072C00096C20B20302096C20B3030207C078697C 83 | :10073C00760208E6F9FB7A00700478768008EB64A0 84 | :10074C00014A70137870E6FE08E6FF1212557863C2 85 | :10075C00A60608A6078068E9FFC3940274809480FB 86 | :10076C00401AEF944D748094805011E925E024FCDC 87 | :10077C00F582E434FFF583E0FEA38020E9FF7E00E0 88 | :10078C00C3944D748094804036EF9461748094804F 89 | :10079C00502D744929F582E43400F583E0FF786329 90 | :1007AC00EEF608EFF61212557863A60608A607783F 91 | :1007BC006A06800B78697603785F76000876007895 92 | :1007CC0074760008760002096C30B20302096C786A 93 | :1007DC0074E6FE08E6FFD3940AEE9400400B1876FC 94 | :1007EC0000087600787802095BC3740A9FFF78636F 95 | :1007FC00E6FE08E6A807088005CEC313CE13D8F989 96 | :10080C001392B3787506E61870010602096C20B2D3 97 | :10081C000302096C30B3237875E6FFC3740A9FFF9B 98 | :10082C007E007401A807088005C333CE33CED8F9F7 99 | :10083C00FFEE785F46F6EF0846F6787506E6187018 100 | :10084C000106D37875E6940A18E694005003020961 101 | :10085C006C760008760078697605C2A8D2AAD2B365 102 | :10086C00785FE6FE08E6FF1212FFEF4E70030209F6 103 | :10087C006C785FE65403F6C3785BE6648094804042 104 | :10088C001C785FE6FE08E6FF9484EE9403500E7825 105 | :10089C005BA60608A607786976FD02096C785FE608 106 | :1008AC00FE08E6FFC3944BEE940050207870E6FCF3 107 | :1008BC0008E6FDEF25E0FFEE33FE74002FF58274A1 108 | :1008CC00003EF583ECF0A3EDF002096C785FE6FED8 109 | :1008DC0008E6FFBE030ABFFC07786A760102096CC2 110 | :1008EC00BE0309BFFB06785976018074BE0309BFAD 111 | :1008FC00F806786A764D8068BE0309BFFD06785904 112 | :10090C007602805CBE0309BFF906786A76028050D5 113 | :10091C00BE0309BFFA06786A76008044BE0309BF9D 114 | :10092C00FE06785976048038EFF47003EE64037099 115 | :10093C002F785BF608F6802820B225787506E61825 116 | :10094C00700106D37875E6940918E6940040117688 117 | :10095C0000087600786976058006C2A8D2AAD2B3C0 118 | :10096C00D007D006D005D004D003D002D001D000DF 119 | :09097C00D0D0D082D083D0E0324B 120 | :0300130002111CBB 121 | :10111C00C0E0C0D075D000C000C006C007C2A8781F 122 | :10112C0069E604600314701520B31230B20F7869AD 123 | :10113C00760078747600087600C2AAD2A830B3354F 124 | :10114C0030B2327869E6FF3395E0FEBEFF16BFFD84 125 | :10115C0013C2A8C2AAC2B378787600087600786960 126 | :10116C0076FC8011786976FFC2A8D2AAD2B37878BF 127 | :10117C007600087600D007D006D000D0D0D0E03270 128 | :0712AC007823E6FE08E6FFCF 129 | :0412B300AB07AA06D5 130 | :1012B7009000AA7411F0E4FDD294D295C294C2951D 131 | :1012C700EAC313139293D295C295EA139293D295D8 132 | :1012D700C295AE02EBA805088005C333CE33CED83E 133 | :1012E700F930E704D2938002C2930DD295EDC394EF 134 | :0712F700087480948040D9C7 135 | :0112FE0022CD 136 | :1010A8007869E6FF3395E0FEC364809480400A784F 137 | :1010B8007906E6187009068006E47878F608F6BE20 138 | :1010C800FF0DBFFF0A786606E6187009068006E479 139 | :1010D8007865F608F6D37879E6948818E69413408C 140 | :1010E8000E7869E6FF3395E0FEBEFF11BFFE0E786D 141 | :1010F80059E6FF3395E0FEEF64044E7016E4785924 142 | :10110800F67878F608F6786976FFC2A8D2AAD2B33C 143 | :04111800120000229F 144 | :1015C400438E40E4F589758DCC758BCCD28ED2AB2D 145 | :0315D400D2AF2271 146 | :100D9600E4782CF67869E6FF3395E0FEBEFF10BFD7 147 | :100DA600FC0D76FE7F017E001215ACD2A8C2AA7891 148 | :100DB60069E6FF3395E0FEEF64FE7002EEF4702CF8 149 | :100DC600D37871E694F818E694024002C2B3785BD1 150 | :100DD600E6FE08E6FF64014E6012D37877E69F18B8 151 | :100DE600E69E5004D2B38004C2B3C2B3786D06E661 152 | :100DF60018700106D3786DE694D018E6940740265D 153 | :100E06007861E6FE08E6FF7870EEF6FE08EFF6FF7C 154 | :100E16007876A60608A607E4786CF608F67BFF7ACD 155 | :100E26001379981211FB1210A87859E6FF3395E052 156 | :100E3600FEEF64024E701876037BFF7A13799C12DC 157 | :100E460011FBE4FFFE12153E7F647E000215AC78AE 158 | :100E560059E6FF3395E0FEEF64034E706AF67BFFBA 159 | :100E66007A1379A41211FBE4782CF6782CE6FFC3EA 160 | :100E7600944B748094804003020F00EF75F002A437 161 | :100E8600FFAEF02400F974003EFA7B019000AFE457 162 | :100E9600F0A37402F012141E7BFF7A1379BA782C31 163 | :100EA600E625E02400F582E43400F583E0FFA3E0C4 164 | :100EB6009000ADCFF0A3EFF01211FB7F017E001280 165 | :100EC60015AC782C0680A47859E6FF3395E0FEEF42 166 | :100ED60064014E7025F6782CF6782CE6FFC3944B09 167 | :100EE600748094805014EF25E02400F582E43400E9 168 | :0A0EF600F58374FFF0A3F00680DF1F 169 | :010F000022CE 170 | :10038B00E47822F608F608F608F608F6782BF6124B 171 | :10039B00155E74FF785BF608F6D2AFC288C2A8C2AE 172 | :1003AB008A1215C4D2AAC290C2917F647E00121524 173 | :1003BB00ACE47822F67822E6FF3395E0FEC3EF94A7 174 | :1003CB004BEE64809480505CEF25E0FFEE33FEC073 175 | :1003DB0006C00774002FF974003EFA7B019000AF42 176 | :1003EB00E4F0A37402F0D007D0061213DF7BFF7A80 177 | :1003FB001379C07822E6FF9000ADF03395E0FEEF65 178 | :10040B0025E0FFEE33FE74002FF58274003EF5837A 179 | :10041B00E0FFA3E09000AECFF0A3EFF01211FB785A 180 | :10042B0022068091D291D2907B017A00799612119B 181 | :10043B00FB785DE6FE08E6FF7823A60608A607E430 182 | :10044B007870F608F67876F608F6782B7601120DAA 183 | :10045B009620B7030204E7120D961212AC782BE626 184 | :10046B00FF3395E0FE7824EF26F618EE36F6785D2E 185 | :10047B00E6FE08E6FF7823E6FC08E6FDD39FEC9E3C 186 | :10048B005006782B760180127861E6FE08E6FFC3F2 187 | :10049B00ED9FEC9E400B782B76FF7823A60608A6E3 188 | :1004AB0007E47822F67822E6FF3395E0FEC3EF945B 189 | :1004BB000AEE64809480500912160430B70306804C 190 | :1004CB00E420B78DE4786CF608F67823E6FE08E6B0 191 | :1004DB00FF7870A60608A607782B760130B70302C3 192 | :1004EB000459120D961212AC782BE6FF3395E0FEF1 193 | :1004FB007824EF26F618EE36F6785DE6FE08E6FF72 194 | :10050B007823E6FC08E6FDD39FEC9E5006782B760D 195 | :10051B000180127861E6FE08E6FFC3ED9FEC9E407A 196 | :10052B000B782B76FF7823A60608A607E47822F62D 197 | :10053B007822E6FF3395E0FEC3EF940AEE648094D5 198 | :10054B0080500912160420B7030680E430B78DE4FF 199 | :10055B00786CF608F67823E6FE08E6FF08A6060890 200 | :10056B00A6077869E6FF3395E0FEEF64FE7002EEB6 201 | :10057B00F46003020646785CE664011846600302E9 202 | :10058B0006467870E6FE08E6FF787326F618EE3618 203 | :10059B00F6786F06E618700106C3786FE6940118BB 204 | :1005AB00E694005003020646E4F608F67856E6FC9D 205 | :1005BB0008E6FD7872E6FA08E6FBD39DEA9C400854 206 | :1005CB00EB9DFDEA9CFC800F7856E6FC08E6C378B1 207 | :1005DB007396FDEC1896FCC3ED9404EC9400503B21 208 | :1005EB00C3EF94F8EE94025032D2B37BFF7A1379B7 209 | :1005FB00C97870E6FF08E69000ADCFF0A3EFF008E6 210 | :10060B00E6FF08E6A3CFF0A3EFF07856E6FF08E687 211 | :10061B00A3CFF0A3EFF01211FB8002C2B37872E606 212 | :10062B00FE08E6FF7857667003EE1866600778568B 213 | :10063B00A60608A607E47872F608F67827E6FE0801 214 | :10064B00E67871667003EE186670107829E6FE087E 215 | :10065B00E67826667003EE1866603F7870E6FE0853 216 | :10066B00E6FF7827A60608A6077825E6FC08E6FD30 217 | :10067B007829A60408A6057D011209857876A606B9 218 | :10068B0008A6077BFF7A1379DA7870E6FF08E69005 219 | :10069B0000ADCFF0A3EFF01211FB782B76FF020425 220 | :0106AB0059F5 221 | :0C11EE00011000010F00010D00010E00B7 222 | :10155E00759850438E01438E0475D7BF75D6FF43E1 223 | :0B156E008E10D2ACD29CC29FD29E22F5 224 | :0B15F8003098FDC298781DA699E6FF10 225 | :0116030022C4 226 | :08160F008F993099FDC2992268 227 | :1015D700120F01FF600C12160F740129F9E43AFA91 228 | :0315E70080EE2271 229 | :03002300020BD1FC 230 | :100BD100C0E0C0F0C083C082C0D075D000C000C0EA 231 | :100BE10001C002C003C004C005C006C007209803AD 232 | :100BF100020D76C298900103E0FBA3E0FAA3E0F9AD 233 | :100C0100E599120F1A900103E0FBA3E0FAA3E0F9C2 234 | :0A0C1100120F01643B6003020D4D59 235 | :100C1B007855F67811E6062413F8760078127602EA 236 | :100C2B00785476007854E6FFC37811964003020D92 237 | :100C3B004474132FF8E6FE6452600DEE64416008B5 238 | :100C4B00EE644C6003020D3E74142FF8E6FEB456AE 239 | :100C5B0007780F7602020D4474152FF8E6FFFD336B 240 | :100C6B0095E0FCC3ED9430EC648094804025EEFD60 241 | :100C7B003395E0FCC3ED9430EC64809480401478A1 242 | :100C8B0054E62414F8E624D075F00AA4FEEF24D021 243 | :100C9B002E801B7854E62414F8E6FFFD3395E0FC18 244 | :100CAB00C3ED9430EC648094804013EF24D0FF901C 245 | :100CBB000103E0FBA3E0FAA3E0F9EF120F1A900196 246 | :100CCB0003E0FBA3E0FAA3E0F9120F01D3946474E1 247 | :100CDB008094805064C374809480405D7854E62483 248 | :100CEB0013F8E6FFB45216780F7601120F01FED3FC 249 | :100CFB00940074809480404108A606803CEFB44178 250 | :100D0B000C780F7601120F01780DF6802C7854E6D3 251 | :100D1B002413F8E6B44C22780F7601120F01FF7EF4 252 | :100D2B000064017005187601800FEF4E700B780E82 253 | :100D3B00F68006785406020C2F781276001876008F 254 | :100D4B008029900103E0FBA3E0FAA3E0F9120F0165 255 | :100D5B00FF7811E6062413F8A6077812760118E639 256 | :100D6B00D3940A7480948040027600309902C29921 257 | :100D7B00D007D006D005D004D003D002D001D000CC 258 | :0B0D8B00D0D0D082D083D0F0D0E03276 259 | :0B11FB009000AAEBF0A3EAF0A3E9F0DB 260 | :10120600782D76010876000876AD9000AAE0F9A35D 261 | :10121600E0FAA3E09000D5C9F0A3EAF0A3E9F078DC 262 | :101226002D860308E6FA08E6F9A3EBF0A3EAF0A395 263 | :10123600E9F07B007A00793012134E7B007A007950 264 | :0E124600301215D7782DA60308760008760022 265 | :011254002277 266 | :02161E000022A8 267 | :07161700D29300D2940022DF 268 | :0D000600D29400D29312161EC29302161E51 269 | :0D001600C29300D29412161ED29302161E41 270 | :10159300C29400300904C2938002D29300D2941201 271 | :0915A300161EC29400D29300222E 272 | :081579001200067FEA1214C8FB 273 | :10158100D29412161E309305C29400C322C2940055 274 | :02159100D32263 275 | :1014C800E4FEEEC39408748094805019C29400EF2F 276 | :1014D80030E705D293008003C29300D29400EF2531 277 | :0B14E800E0FF0E80DDC29400D29300F4 278 | :0114F30022D6 279 | :10145D00C29400D29300E4FEEEFD7C00C3940874A8 280 | :10146D008094805025D29400EF3093054401FF8085 281 | :10147D000354FEFF00C29400C3ED9407EC64809406 282 | :0A148D00805004EF25E0FF0E80CE32 283 | :011497002232 284 | :10151B00AB07121579400122AF031214C8121581C3 285 | :10152B00400122AF051214C812158140012212008E 286 | :03153B0016D322A2 287 | :02149800AD079E 288 | :10149A0012157940037F0022AF051214C8C209123F 289 | :1014AA0015931200067FEB1214C812158140037FB0 290 | :0D14BA00002212145DC209121593120016D3 291 | :0114C7002202 292 | :0E15EA00E4F5C7F5C5F5C675C3FF75C4FF224D 293 | :1013DF00AD07AC06C2AF75C78375C501ECF5C3AFDA 294 | :1013EF00058FC475C65A75C6A500E5C2120F1A0D32 295 | :1013FF00BD00010C740129F9E43AFA9000AF74FFB3 296 | :0F140F00F5F0120F9345F070D01215EAD2AF220C 297 | :10153E00AD07AC06C2AFECF5C3AF058FC475C7835C 298 | :10154E0075C50375C65A75C6A5001215EAD2AF2227 299 | :10141E00AD07AC06C2AF75C78375C502ECF5C3AF99 300 | :10142E00058FC4120F01F5C275C65A75C6A5000DFB 301 | :10143E00BD00010C740129F9E43AFA9000AF74FF73 302 | :0F144E00F5F0120F9345F070D01215EAD2AF22CD 303 | :1010280002038BE493A3F8E493A34003F68001F250 304 | :1010380008DFF48029E493A3F85407240CC8C333C9 305 | :10104800C4540F4420C8834004F456800146F6DF98 306 | :10105800E4800B010204081020408090118CE47E8B 307 | :10106800019360BCA3FF543F30E509541FFEE4938D 308 | :10107800A360010ECF54C025E060A840B8E493A354 309 | :10108800FAE493A3F8E493A3C8C582C8CAC583CA7F 310 | :10109800F0A3C8C582C8CAC583CADFE9DEE780BE37 311 | :0111FA0000F4 312 | :100F0100BB010689828A83E0225002E722BBFE02EE 313 | :090F1100E32289828A83E4932221 314 | :100F1A00BB010689828A83F0225002F722BBFE01B6 315 | :020F2A00F322B0 316 | :100F2C00EF8DF0A4A8F0CF8CF0A428CE8DF0A42ED9 317 | :020F3C00FE2293 318 | :100F3E00BC000BBE0029EF8DF084FFADF022E4CC97 319 | :100F4E00F875F008EF2FFFEE33FEEC33FCEE9DEC60 320 | :100F5E00984005FCEE9DFE0FD5F0E9E4CEFD22EDA6 321 | :100F6E00F8F5F0EE8420D21CFEADF075F008EF2FF0 322 | :100F7E00FFED33FD4007985006D5F0F222C398FDE1 323 | :050F8E000FD5F0EA227E 324 | :100F9300C5F0F8A3E028F0C5F0F8E58215827002E9 325 | :060FA3001583E038F02286 326 | :10134E009000D5E0FFA3E0FEA3E0CF9000DEF0A377 327 | :10135E00EEF0A3EFF09000D8E0CBF0A3E0CAF0A33C 328 | :10136E00E0C9F07F229000E1AD82AC83120F018DB7 329 | :10137E00828C83F0A309E970010ADFEC9000D8E0BB 330 | :0A138E00FBA3E0FAA3E0F902008BD4 331 | :10002600E50824DEF582E43400F583E00508229035 332 | :1000360000DB3007039000DEE475F001120FD602F4 333 | :100046000F012000E97F2ED2008018EF540F249074 334 | :10005600D43440D4FF30040BEF24BFB41A0050034D 335 | :100066002461FFE50960021509050CE50C7002051F 336 | :100076000B30070E9000DBE475F001120FD6EF028D 337 | :100086000F1A0214F47403D2078003E4C207F508BA 338 | :100096009000DB120FEDE4F509F50BF50CE50960B0 339 | :1000A600077F2012006980F5750AFFC201C200C2EF 340 | :1000B60002C203C205C206C208120035FF700D3027 341 | :1000C60007057F0012007AAF0CAE0B22B4255FC283 342 | :1000D600D5C204120035FF24D0B40A00501A75F0B8 343 | :1000E6000A780930D50508B6FF0106C6A426F6200B 344 | :1000F600D5047002D20380D924CFB41A00EF50047D 345 | :10010600C2E5D20402027BD20180C6D20080C0D2F0 346 | :100116000280BCD2D580BAD20580B47F2012006995 347 | :100126002002077401B5090040F1120026FF1200F3 348 | :10013600690200A3D208D2068095120026FB12009F 349 | :1001460026FA120026F94A4B7006794C7A037BFF91 350 | :1001560020022EE509602A7E008E82758300120F2A 351 | :10016600A960060EEE650A70F0C2D5EBC0E0EAC0E3 352 | :10017600E0E9C0E0EE1202C2D0E0F9D0E0FAD0E049 353 | :10018600FB120F01FF60AAEBC0E0EAC0E0E9C0E0A5 354 | :10019600120069D0E02401F9D0E03400FAD0E0FB87 355 | :1001A600E50A0460DCD50AD980877BFF7A0279BE2E 356 | :1001B600D202809C791080027908C206C2088008A3 357 | :1001C600D2D5790A8004790AC2D5E50A047002F507 358 | :1001D6000AE4FAFDFEFF120026FC7B08200113123A 359 | :1001E6000026FD7B1030000A120026FE120026FFB4 360 | :1001F6007B20EC3382D592D55013C3E43000069FA2 361 | :10020600FFE49EFEE42001039DFDE49CFCE4CBF8A4 362 | :10021600C201EC700CCFCECDCCE824F8F870F38098 363 | :1002260017C3EF33FFEE33FEED33FDEC33FCEB3358 364 | :10023600FB994002FB0FD8E9EB300105F8D0E0C48A 365 | :1002460048B201C0E00AEC4D4E4F78207B0070C2E8 366 | :10025600EAB50A0040BCC0E01202C4D0F0D0E020EB 367 | :100266000104C4C0E0C4B201C0F0120052D0F0D5FF 368 | :10027600F0EB0200A3120FF601405301BA58011128 369 | :100286004C010D4201BE4F01C64401C64901264339 370 | :0802960001CC5501B04601B096 371 | :10029E004501B047036C5001152D01192E013C2B61 372 | :1002AE00011D23013A2003552A00D54800000134D0 373 | :1002BE003F3F3F00790AA2D5200314300509B9103B 374 | :1002CE00020404B9080104A2D5200602500104203C 375 | :1002DE0002689202B509005034C0E07F2030031945 376 | :1002EE007F30A20272067205500F12031BC202C2A9 377 | :1002FE0006C205C2087F30800F300503E9C0E01248 378 | :10030E000069300503D0E0F9D0E0B509CC3005170F 379 | :10031E007F30B9100C1200697F583004077F788047 380 | :10032E0003B908031200693002057F2D0200697FB0 381 | :10033E00202008F87F2B2006F322920280CF286E11 382 | :10034E00756C6C2900D2011200263001F8C20178BA 383 | :10035E000930D50108F60200D52D50434958120038 384 | :10036E00262403B405004001E49003679312005A5B 385 | :0D037E00743A12005AD2037509040201BA44 386 | :100FA900BB010CE58229F582E5833AF583E02250FD 387 | :100FB90006E92582F8E622BBFE06E92582F8E22247 388 | :0D0FC900E58229F582E5833AF583E4932261 389 | :100FD600F8E0FBA3A3E0F925F0F0E58215827002A4 390 | :070FE6001583E0FA38F02248 391 | :090FED00EBF0A3EAF0A3E9F02205 392 | :100FF600D083D082F8E4937012740193700DA3A38A 393 | :1010060093F8740193F5828883E47374029368609D 394 | :06101600EFA3A3A380DF9D 395 | :1014F400EFB40A07740D1214FF740A309811A899F6 396 | :10150400B8130CC2983098FDA899C298B811F63057 397 | :0715140099FDC299F599222F 398 | :00000001FF 399 | -------------------------------------------------------------------------------- /hex/V1.3_STM32/V1.2stm32_20240211.hex: -------------------------------------------------------------------------------- 1 | :020000040800F2 2 | :100000006809002061020008352F0008DD2A000879 3 | :1000100000000000000000000000000000000000E0 4 | :100020000000000000000000000000007530000823 5 | :100030000000000000000000372F000877300008A3 6 | :100040007302000800000000730200087302000839 7 | :10005000730200087302000873020008351A0008D2 8 | :100060000000000073020008730200087302000819 9 | :100070007302000873020008730200080000000009 10 | :100080007302000800000000000000007302000876 11 | :1000900000000000730200087302000873020008E9 12 | :1000A000730200087302000873020008730200085C 13 | :1000B00073020008000000000000000000000000C3 14 | :1000C00000F002F800F0BDF80CA030C80838241881 15 | :1000D0002D18A246671EAB4654465D46AC4201D180 16 | :1000E00000F0AFF87E460F3E0FCCB64601263342F5 17 | :1000F00000D0FB1AA246AB4633431847D43E00005B 18 | :10010000F43E0000103A02D378C878C1FAD85207FA 19 | :1001100001D330C830C101D504680C6070470000BD 20 | :100120000023002400250026103A01D378C1FBD813 21 | :10013000520700D330C100D50B60704710B56E294F 22 | :1001400002D100F057FA10BD702902D100F091FBE6 23 | :1001500010BD662902D103F067FE10BD652902D1EA 24 | :1001600003F062FE10BD672902D103F05DFE10BDF1 25 | :10017000612902D103F060FE10BD03681B0A01D3A0 26 | :1001800080231943692902D100F0FEF910BD6429CA 27 | :1001900002D100F0F9F910BD752902D100F0F4F98F 28 | :1001A00010BD6F2902D100F00FFB10BD782902D1DC 29 | :1001B00000F04CFB10BDE92902D100F0ABFA10BDF4 30 | :1001C000E42902D100F0A6FA10BDF52902D100F011 31 | :1001D000A1FA10BDEF2902D100F002FB10BDF829F1 32 | :1001E00002D100F041FB10BD0368DB0901D380237D 33 | :1001F0001943632902D101F022F810BD732902D1FD 34 | :1002000001F025F810BDE32902D101F02FF810BD4F 35 | :10021000F32902D101F032F810BD002010BD1FB546 36 | :1002200001F08CF804000020002103F0E7FD401CE1 37 | :1002300060600020002103F0CBFDE0601FBD10B521 38 | :1002400010BD01F053F81146FFF7E9FF03F0D0FBB2 39 | :1002500001F074FB03B4FFF7F2FF03BC01F0BCFB39 40 | :100260000748804707480047FEE7FEE7FEE7FEE74E 41 | :10027000FEE7FEE704480549054A064B70470000C3 42 | :10028000D9300008C1000008680300206809002078 43 | :1002900068050020680500201CB50C46064B7B4411 44 | :1002A00069460090204600F0BEF9044600206946E9 45 | :1002B00000F0CCF920461CBDAB03000030B5441C57 46 | :1002C00003E00178401C00290DD08107F9D10B4BC8 47 | :1002D000DD0104C8D11A91432940FAD0001B0A0657 48 | :1002E00003D0C01E30BD001B30BD0A0401D0801EEB 49 | :1002F00030BD0902FCD0401E30BD000001010101EB 50 | :1003000001E004C0091F0429FBD28B0701D502803C 51 | :10031000801CC90700D00270704700290BD0C307AA 52 | :1003200002D00270401C491E022904D3830702D563 53 | :100330000280801C891EE3E70022EEE70022DFE74F 54 | :100340000378C2781946437812061B021943837852 55 | :10035000C0781B04194311430902090A0006084327 56 | :100360007047002203098B422CD3030A8B4211D31E 57 | :1003700000239C464EE003460B433CD40022430836 58 | :100380008B4231D303098B421CD3030A8B4201D326 59 | :1003900094463FE0C3098B4201D3CB01C01A5241BE 60 | :1003A00083098B4201D38B01C01A524143098B420E 61 | :1003B00001D34B01C01A524103098B4201D30B01F7 62 | :1003C000C01A5241C3088B4201D3CB00C01A52411C 63 | :1003D00083088B4201D38B00C01A524143088B42E1 64 | :1003E00001D34B00C01A5241411A00D2014652417A 65 | :1003F000104670475DE0CA0F00D04942031000D399 66 | :100400004042534000229C4603098B422DD3030AED 67 | :100410008B4212D3FC22890112BA030A8B420CD3FD 68 | :10042000890192118B4208D3890192118B4204D326 69 | :1004300089013AD0921100E08909C3098B4201D3A6 70 | :10044000CB01C01A524183098B4201D38B01C01AE0 71 | :10045000524143098B4201D34B01C01A5241030957 72 | :100460008B4201D30B01C01A5241C3088B4201D306 73 | :10047000CB00C01A524183088B4201D38B00C01AB3 74 | :100480005241D9D243088B4201D34B00C01A52418A 75 | :10049000411A00D20146634652415B10104601D317 76 | :1004A0004042002B00D54942704763465B1000D3A1 77 | :1004B000404201B50020C046C04602BD70477047AB 78 | :1004C000704770B5044685690068C10601D53026BD 79 | :1004D00000E02026C00707D070BD62683046A168E2 80 | :1004E0009047206A401C20626D1EF6D570BD70B525 81 | :1004F000044685690078C00707D170BD6268A168AD 82 | :1005000020209047206A401C20626D1EF6D570BDE9 83 | :1005100009684A0501D540B27047C905FCD500B24B 84 | :10052000704709684A0501D5C0B27047C905FCD5B6 85 | :1005300080B2704770B50C460546012A05D0287870 86 | :10054000800600D5EA69002302E0012305E05B1C78 87 | :10055000934202D2E05C0028F9D1A869E618C01ADB 88 | :10056000A861286AC01828622846FFF7AAFF04E09D 89 | :100570006A682078A968641C9047B442F8D328467A 90 | :10058000FFF7B5FF70BD0000F7B5002575291068AD 91 | :10059000009914A611D0FFF7BBFF002802DA4042F1 92 | :1005A00011A608E0009909688A0701D50FA602E0A4 93 | :1005B000490704D50EA6012501E0FFF7B2FF009F11 94 | :1005C0000024243704E000F07DFE30313955641CEE 95 | :1005D0000028F8D12B4632462146009800F057FA01 96 | :1005E000FEBD0000000000002D0000002B000000F8 97 | :1005F0002000000011680268006A530501D50870E8 98 | :1006000009E0D30501D5088005E0130602D5C2171D 99 | :1006100005C100E0086001207047000001694A1C24 100 | :1006200002610878704700B58FB0029100210591F2 101 | :10063000054901937944039111460490684600F0FE 102 | :1006400025F90FB000BD0000E5FFFFFF0A6810703C 103 | :10065000521C0A6070470000F7B50446154686B084 104 | :100660002B487844002703C83E460090019111E0D2 105 | :1006700007986A467100415A02A800F003FE411C27 106 | :1006800007D02178890603D5E269391891420ED83E 107 | :100690003F18761C2078800602D5E069B84206DD56 108 | :1006A000AE42E5DB07987100405A0028E0D1A0690E 109 | :1006B000C01BA0612046FFF704FF154878445A3854 110 | :1006C00003C800900020019116E041006A46079897 111 | :1006D000415A02A800F0D6FD0590401C0AD0002522 112 | :1006E00005E0626802A8A168405D90476D1C05980E 113 | :1006F0008542F6D30498401CB0420490E5DB206AA2 114 | :10070000C01920622046FFF7F2FE09B0F0BD0000DC 115 | :100710006E380000F7B5D21D0025D20815A6D2000C 116 | :10072000F52905CA11D0002A05DA0021404291417D 117 | :1007300011A60A4608E0009909688B0701D50FA6A3 118 | :1007400002E0490701D50EA601251146009F0024AD 119 | :10075000243704E000F05EF930323A55641C02465A 120 | :100760000A43F7D12B4632462146009800F08FF914 121 | :10077000FEBD0000000000002D0000002B00000066 122 | :100780002000000070B504460021243408E055071D 123 | :10079000D2086D0F303565545D072A43DB08491CCC 124 | :1007A00015461D43F3D10468002310A2250708D580 125 | :1007B00020252C400C4304D0C46901230CA2641EE4 126 | :1007C000C46100F064F970BD10B50446214610689C 127 | :1007D000FFF7A7FE002302462046FFF7D3FF10BD18 128 | :1007E000D21DD108C9000CC9CCE7000000000000F0 129 | :1007F00030000000F8B50F460188090502D5224CEB 130 | :100800007C4402E0204C7C440E3405460021243513 131 | :1008100008E016071209360FA65D6E541E07324314 132 | :100820001B09491C16461E43F3D1224604780023B7 133 | :10083000240705D5702F06D0002901D002231132DC 134 | :1008400000F025F9F8BD01231032F9E770B5044630 135 | :100850000D4621461068FFF764FE00230246294634 136 | :100860002046FFF7C7FF70BDD21DD308DB000CCBBD 137 | :10087000C0E730B4036820241268234303600823D0 138 | :10088000C36130BC0023B5E7D8360000F3B5044699 139 | :10089000002081B020622046E1688847002872D09D 140 | :1008A000252802D06268A168ABE0594F00267F443A 141 | :1008B0002046E16888472028054608DB312D06D20E 142 | :1008C000781920380078002801D00643F0E7B007F7 143 | :1008D00001D5042086430020E0610746A0612A2D4F 144 | :1008E0000AD0284602F02EFE002827D0B8000019B2 145 | :1008F000303D0090856119E00298BA00121902C8D3 146 | :10090000916102902046E1688847012F054617D182 147 | :10091000E06900281FDA202086431CE000980A21A5 148 | :100920008069484300994019303888612046E16861 149 | :100930008847054602F006FE0028EFD1012F0AD0B5 150 | :100940002E2D08D12046E168884705462020064321 151 | :100950007F1C022FC3DBA069002803DA4042A0619C 152 | :1009600001200643F00701D0102086436C2D0BD0E8 153 | :10097000682D09D04C2D3CD06A2D38D0742D38D03C 154 | :100980007A2D36D016E040E0E1682F4620468847B1 155 | :10099000B842054609D16C2F29D001208002E168B8 156 | :1009A000064320468847054604E06C2F1DD0FF20F3 157 | :1009B00001300643002D28D028464138192803D895 158 | :1009C0000120C00206432035204626602946029AAF 159 | :1009D0001646FFF7B3FB002810D001280BD0F61DF8 160 | :1009E000F008C0000830029055E74020E1E7802081 161 | :1009F000D5E70020D3E7361D02964CE7626828460B 162 | :100A0000A1689047206A401C44E7206AFEBD0000B0 163 | :100A1000523600000B4670B502468907800808432D 164 | :100A200019469D08141AA941250908070543080914 165 | :100A30002C194841250A01060D43010A2C19414190 166 | :100A4000200C0D0428430D0C00194D4100214019C4 167 | :100A50004D41C00869070843E908840F8D0025430C 168 | :100A6000840024184D4124196D41121BAB4107E04D 169 | :100A70000925ED432C11521963410024401C6141AA 170 | :100A80001C460A250026551BB441F1D270BDFFB5A6 171 | :100A900004460D4681B0243000902168880604D5B4 172 | :100AA0001022E0699143216000E00120A84201DDAD 173 | :100AB000471B00E000270498A1697A191018081A4A 174 | :100AC000A0612078C00602D42046FFF7FAFC002679 175 | :100AD00008E003986268A168805D9047206A401C26 176 | :100AE000761C206204988642F3DB2078C0060AD583 177 | :100AF0002046FFF7E6FC06E06268A16830209047D8 178 | :100B0000206A401C206238467F1E0028F4DC07E083 179 | :100B100000986268A168405D9047206A401C20628E 180 | :100B200028466D1E0028F3DC2046FFF7E0FC207805 181 | :100B3000000602D5022005B0F0BD0120FBE7000051 182 | :100B40007047FFB50C461E468FB003CA0890099146 183 | :100B50004F007D0D00D16D1E002108460020C046CB 184 | :100B60000321099A89050840002A03DA82008018C7 185 | :100B700040080840800D01280A9002DD0020C04393 186 | :100B80000A90089807430DD0EF48F04928184843C9 187 | :100B90000714189800281DD07542291E1DDD0A98DB 188 | :100BA00042421BE01898012802D00020302104E0C6 189 | :100BB0000020F24305E02154401CB042FBDB3046EC 190 | :100BC0000022189B002121540F998B600A60486015 191 | :100BD00013B0F0BDBD1B6D1CDFE70A9A002900DAD7 192 | :100BE00069420BA800F0F2FB0BAB07CB03AB07C3CA 193 | :100BF0000899099800F04EFC6B4607C30146D4489B 194 | :100C00000918002D00910ADDD14903980A9A49423A 195 | :100C1000401803A90390684600F061FE07E00399BD 196 | :100C20000A9A081803A90390684600F02EFE6B4646 197 | :100C300007C30004000C03D00020C043410800E0BB 198 | :100C40001046189A002A03D00022009215461EE092 199 | :100C5000751E05D4FFF7DEFE303262556D1EF9D5E4 200 | :100C600001220843079602D000227F1C04E020786E 201 | :100C7000302801D100227F1E002A069789D01EE06D 202 | :100C8000112D07DAFFF7C6FE303262556D1C0246A1 203 | :100C90000A43F5D1084303D00098002819D00EE08C 204 | :100CA0000021681E05E0235C625C63542254401EF0 205 | :100CB000491C8142F7DBA81B401E07950690079A46 206 | :100CC00018990020A0540F98079B069A81600CC0C9 207 | :100CD0007EE71126002018905BE7D21DF0B50D4687 208 | :100CE0000446D10893B0C90003C90C900D9102F0DD 209 | :100CF000F1FB02460D98C00F01D02D2007E02068BF 210 | :100D0000810701D52B2002E04007C00F4001032AD4 211 | :100D10000F9001D0072A05DB03462946204600F044 212 | :100D200011FB0EE12078800601D5E76900E0062777 213 | :100D30002846652D04D0662814D0672D69D12DE092 214 | :100D40000020112F009001DB112300E07B1C0CAA76 215 | :100D500003A910A8FFF7F5FE1199002610987D1C35 216 | :100D60000E9142E001203B460CAAC0070B900120E7 217 | :100D7000009003A910A8FFF7E4FE119D12981099A6 218 | :100D8000002600280E9501D1781C0D18781B02D47E 219 | :100D900046427D1C761EE81B00903AE0012F00DAE7 220 | :100DA00001270020112F009001DD112300E03B46B8 221 | :100DB0000CAA03A910A8FFF7C4FE11993D4610988C 222 | :100DC00000260E91217809070BD40E99A94200DA6A 223 | :100DD0000D4603A9012D04DD4A19203AD27F302A9D 224 | :100DE00006D0B84201DA011D04DA012100910FE0BA 225 | :100DF0006D1EEFE7002802DC86192D1A03E0411C66 226 | :100E0000A94200DD0D46801B401C00900120C00758 227 | :100E10000B902078000705D40098A84202DB002040 228 | :100E2000C043009069460020C8720B98012102AFB0 229 | :100E30000337C907884225D0022010902B2011903B 230 | :100E40000B9800280BDA40420B902D20119006E001 231 | :100E50000B9800F037FA30317F1E0B9039701099E3 232 | :100E6000481E00291090F3DC0B980028F0D111984F 233 | :100E70007F1E38702088000501D5452000E06520E0 234 | :100E80007F1E387001A8C01BC01D0B900F98002852 235 | :100E900000D0012041190098C01709180B980818B4 236 | :100EA000A169081A401EA0612078C00602D420461D 237 | :100EB000FFF707FB0F98002805D06268A1689047EC 238 | :100EC000206A401C20622078C00625D52046FFF706 239 | :100ED000F8FA21E0002E07DB0E98B04204DD03A8EB 240 | :100EE0006268805DA16802E06268A1683020904776 241 | :100EF000206A761C401C20620098401E002800904A 242 | :100F00000AD100F01BFAC06862680168405CA16801 243 | :100F10009047206A401C206228466D1E0028D9DCBC 244 | :100F200007E062683878A1687F1C9047206A401CFF 245 | :100F300020620B99481E00290B90F2DC2046FFF737 246 | :100F4000D6FA032044E6000001FCFFFF104D00002C 247 | :100F5000E1DFFFFFD21DF0B504460D46D0088DB08D 248 | :100F6000C000466807683146384602F0B3FA0246C8 249 | :100F7000F00F01D02D2307E02068810701D52B2336 250 | :100F800002E04007C00F43016846002B037001D008 251 | :100F9000012000E00020032A0A9001D0072A04DB88 252 | :100FA0002946204600F0CEF92BE12078800601D4B6 253 | :100FB0000D2500E0E5697000400D0D2D01904BDA24 254 | :100FC000300D00210B9008460020C0460321890502 255 | :100FD0000840002E05DA82008018C20F1018401059 256 | :100FE00008408015012801DD0020C043A90000232E 257 | :100FF000182906D39C460A460123183A1B07D340FA 258 | :1010000003E001221205CA4094460C31202902D384 259 | :101010003A46203900E032468A40002802DD002AA4 260 | :1010200006D119E0002817D10121C9078A4213D33C 261 | :10103000194663467F185E41002806D10120C0078B 262 | :10104000824202D1084687439E430B98310D81426C 263 | :1010500002D00198401C01902088000502D57049FB 264 | :10106000794402E06E49794419396B460A98302276 265 | :101070001A540A980A7C401C1A54401C0A90019881 266 | :10108000002801DC302000E031201872019A012094 267 | :10109000002A02D0634BD21804E072003A4302D017 268 | :1010A000604A521C0192002D02DC2278120703D5FF 269 | :1010B0006A462E20507202200022864694460CE09A 270 | :1010C00032033601120F6D1E8B5C02AA1354624666 271 | :1010D000521C401C9446052A01DA002DF0DC002247 272 | :1010E00002AE08E03B0F3F01CB5C521C6D1E335437 273 | :1010F000401C082A01DA002DF4DC2278920601D582 274 | :101100000FE0401E704504DD3218203AD27F302AAD 275 | :10111000F7D0002805DD3218203AD27F2E2A00D1E0 276 | :10112000401E002D03DD3E223254401C6D1E497CC2 277 | :1011300031540199401C002906DA2D21471C3154F5 278 | :1011400001984042019003E02B21471C3154019843 279 | :101150007D21C900884206DBFFF70DF93030F055DC 280 | :101160007F1C019101E0642808DB01986421FFF7EE 281 | :1011700002F93030F0557F1C019101E00A2806DBAE 282 | :1011800001980A21FFF7F7F83030F0557F1C0198DD 283 | :101190000A21FFF7F0F83031F1550A98A1697F1C58 284 | :1011A0007A191018081AA0612078C00602D42046C7 285 | :1011B000FFF787F9216A6E460A980818206204E052 286 | :1011C00062683078A168761C90470A98401E0A90A1 287 | :1011D000401CF5D12078C00602D52046FFF771F9F2 288 | :1011E00002AE09E03078761C3E280DD06268A16816 289 | :1011F0009047206A401C20627F1EF3D22046FFF7F2 290 | :1012000076F90DB00320F0BD206A4019206203E09A 291 | :101210006268A168302090476D1EEDD3F8E70000AA 292 | :10122000C42E000001FCFFFF10B54369002B02D063 293 | :10123000C046C04601E0FFF77DF9012010BD1278DD 294 | :10124000014624310A7000224A700122ECE711683D 295 | :101250000022D243E8E710B54369002B02D0C04614 296 | :10126000C04601E0FFF7F8F9012010BD12880146E1 297 | :10127000243182840022C2840122ECE7116800221A 298 | :10128000D243E8E770B516460C46054600F04EF826 299 | :101290000368FF200230C05C012807D0FF2C0ED865 300 | :1012A000185D00280BD001202C7070BDFF33324632 301 | :1012B000214608331868C3182846984770BD002097 302 | :1012C000C04370BD01468008081A02091018020ABE 303 | :1012D0001018020C1018C008820012185200891A47 304 | :1012E00001E0401C0A390A29FBD27047754600F01C 305 | :1012F0002BFBAE46050069465346C008C000854634 306 | :1013000018B020B5FEF7B6FF60BC00274908B64606 307 | :101310000026C0C5C0C5C0C5C0C5C0C5C0C5C0C504 308 | :10132000C0C5403D49008D467047000010B500F033 309 | :1013300005F8001D10BD00BFC52A00000048704719 310 | :1013400024030020F8B51F46044601230068DB0291 311 | :10135000032601461840072A05DB002801D017A5FF 312 | :1013600006E017A504E0002801D016A500E016A5A8 313 | :10137000102081432160A069C01E002FA06101D010 314 | :10138000401EA0612046FFF79CF8002F09D0384688 315 | :101390006268A1689047206A401C2062C01C2062DD 316 | :1013A00006E0206AFAE762682878A1686D1C904719 317 | :1013B000761EF8D22046FFF79AF8F8BD4E414E004F 318 | :1013C0006E616E00494E4600696E6600F7B51646BE 319 | :1013D0008AB02F4878446C4603467C33C06F5A6805 320 | :1013E0009B680DC42A487844763003AC0DC80DC400 321 | :1013F0003720C001081837211B30FEF7BCFF054617 322 | :101400000C46803D1B3C02D56442012000E00020D8 323 | :10141000002709900FE0E0070BD00C201C4978430F 324 | :10142000794432464C394118684600F02EFA6B4632 325 | :1014300007C364107F1C002CEDD1154F7F442C3F57 326 | :1014400015E0E80711D02001C0190EC806910893D5 327 | :1014500007920068F04201D198190890324606A917 328 | :1014600003A800F012FA03AB07C36D10641C002D33 329 | :10147000E7D1324669460998002803A802D000F057 330 | :101480002EFA01E000F001FA0A9B07C30DB0F0BD8F 331 | :10149000642B0000034640000A4610B5400D0BD0F7 332 | :1014A0000121C9070F24A40200191C036408214369 333 | :1014B000540D2143D20207E000210120F2E7D40FAE 334 | :1014C000490021435200401E0029F8DADB0FDB07F8 335 | :1014D000184310BDFFB50D46144685B048685168E5 336 | :1014E00001F0D2FF00910190A868A16801F0CCFF43 337 | :1014F00002910390A868616801F0C6FF029A121871 338 | :101500008242029201D2012000E00020019A0B18D1 339 | :10151000D2180028019202D08A4202D903E08A42FE 340 | :1015200001D2012000E000200099081800906868AE 341 | :10153000A16801F0A9FF029A12188242029201D218 342 | :10154000012000E00020019A0B18D2180028019217 343 | :1015500002D08A4202D903E08A4201D2012000E08F 344 | :101560000020009908180090286821684000490070 345 | :10157000400849084018EE49471814E00199400016 346 | :10158000C90F08430090019802994000C90F084311 347 | :101590000190029803994000C90F084302900398F4 348 | :1015A00040007F1E039000980028E7DA0898002882 349 | :1015B00001D0E04E00E00026B74228DAF71BF8061B 350 | :1015C000C00E15D0029B2021091A039A8B401A43A2 351 | :1015D0000392029A019BC2408B401A430292019AE5 352 | :1015E000009BC2408B4000991A430192C140009178 353 | :1015F0007A110BD06B460320811A01D5002101E03E 354 | :10160000890059588700401ED951F5D537460398AF 355 | :101610000299002800D00120014308980291002877 356 | :1016200008460CD0002800D001200199019A4905F4 357 | :1016300008430121D20AC902D202019200E001212D 358 | :101640000E9B0122D207012B02D0002B03D013E006 359 | :10165000002807D116E0904204D890420CD1019B9B 360 | :101660000B4209D0019B5918019105D10099491CE1 361 | :10167000009101D17F1C0092002803D01021084660 362 | :101680000020C04628682168019B009A4840C10F8D 363 | :101690000598C90739430EC009B0F0BDFFB587B042 364 | :1016A000099A08980899536892684068896896462C 365 | :1016B0000022039317469446089A12685300099A29 366 | :1016C0005B081268520052089A1A9B4BD4180A9A67 367 | :1016D000002A01D0352200E0402206920022012398 368 | :1016E00015460492DB07059324E0002D05D17546CD 369 | :1016F0000346039E4D1BB34109D375466646039BC3 370 | :10170000491B049D9841059B7519AC465F41634692 371 | :101710003B4308D0059B049EDD0776082E435B08FB 372 | :101720000496059301E0521E641EC50FED0749188B 373 | :101730004041521C069B9A42D7DB002D04D17546CE 374 | :10174000039A6B1A824101D203200CE0039A0B46E4 375 | :101750006B404240134303D0014303D0012002E019 376 | :10176000022000E0002061460191002100970291D3 377 | :101770000A99002905D06146400201436D4B019151 378 | :1017800002E08007002302909C423ADA1A1BD0063E 379 | :10179000C00E15D0029D2021019C091AC5408C4025 380 | :1017A0002543029C8C4000D001242543019C0295D6 381 | :1017B0003D46C4408D4039462C43C14001940091C0 382 | :1017C00054111DD06D460221002202290CD10320A4 383 | :1017D000001B07E0002804DB8600AE59002E00D075 384 | :1017E0000122401C0328F5DB081B02D588002A5083 385 | :1017F00004E08000285810438A00A850491EE3D511 386 | :101800001C460A98002802980CD0002800D001201D 387 | :101810000199019A490508430121D20AC902D2025D 388 | :10182000019200E00121109B0122D207012B02D07E 389 | :10183000002B03D013E0002807D116E0904204D813 390 | :1018400090420CD1019B0B4209D0019B5918019188 391 | :1018500005D10099491C009101D1641C0092002817 392 | :1018600003D0102108460020C04608980999019A23 393 | :101870000068096848400099C30F0798DB072343B5 394 | :101880000360826041600BB0F0BD1FB50023009281 395 | :101890000A46014601A8FFF71DFE01AB07CB04B0C5 396 | :1018A00010BD1FB5012300920A46014601A8FFF7AB 397 | :1018B00011FE01AB0F2407CBA402C30F4000DB07CE 398 | :1018C0004008001B002900DB0020490000054908F2 399 | :1018D000CC0A204349051843D20A1143DFE71FB55C 400 | :1018E000002300920A46014601A8FFF7D7FE01AB8C 401 | :1018F00007CBD4E71FB5012300920A46014601A891 402 | :10190000FFF7CCFE01AB0F2407CBA402C30F4000AE 403 | :10191000DB074008001B002900DB00204900000510 404 | :101920004908CC0A204349051843D20A1143B6E7B7 405 | :1019300002C0FFFF013C0000FF3F00000446C0461C 406 | :10194000C0462046FEF786FC00487047040300208E 407 | :10195000024670B50A4392072AD11E4DEE0104C813 408 | :1019600008C9541B9443344017D0D0B2D9B2401A9E 409 | :101970002106014310D190B299B2401A21040143CB 410 | :101980000AD110021902000A090A401A2102014371 411 | :1019900002D1100E190E401A70BD9A42DFD010BA53 412 | :1019A00019BA884201D9012070BD0020C04370BD22 413 | :1019B00002780B78401C491C002A09D09A4207D1B2 414 | :1019C00002780B78401C491C002A01D09A42EFD0C3 415 | :1019D000D01A70BD0101010101491820ABBEFEE71C 416 | :1019E000260002007047002211460346CB40DB0769 417 | :1019F00001D0521CD2B2491CC9B20A29F5D3D10771 418 | :101A000002D0012189020843704700221146034693 419 | :101A1000CB40DB0701D0521CD2B2491CC9B20A2903 420 | :101A2000F5D3D107800AC90F884201D10120704740 421 | :101A30000020704710B50120C00200F03FF90120DE 422 | :101A4000000300F03BF910BD7047000003494A69EC 423 | :101A500001231B04184302434A61704700200240DF 424 | :101A6000044A5069044BC90018400143034801432C 425 | :101A7000516170470020024007E0FFFF02000100B3 426 | :101A800030B505494C6901252C434C610260BFF318 427 | :101A90006F8F436030BD00000020024030B50B4C1A 428 | :101AA000002362690125AD042A436261EFF31082CD 429 | :101AB00072B620C95B1C20C0DBB2402BF9D3206971 430 | :101AC000C003FCD482F3108830BD00000020024027 431 | :101AD000F8B5054600F0DCF9471901263604114C2B 432 | :101AE00003E000F0D5F9B84214D220693042F8D1B1 433 | :101AF00021690D4801400D48206103D00C48416028 434 | :101B00000120F8BD00F0C4F9451905E000F0C0F966 435 | :101B1000A84201D30320F8BD20694003F6D4002079 436 | :101B2000F8BD000000200240FA830000FB830000A3 437 | :101B3000E802002070B5044600F0AAF90546601CD2 438 | :101B400002D004480078241800F0A2F9401BA042FB 439 | :101B5000FAD370BD50000020F8B51F4E044630780F 440 | :101B60000F4601280AD001203070002070607D20CF 441 | :101B7000C000FFF7ADFF002802D029E00220F8BD29 442 | :101B8000042161602268042A03D0491F3960A568D6 443 | :101B900014E00846FFF75AFF7D20C000FFF798FFCA 444 | :101BA00016E029466068FFF75BFF7D20C000FFF765 445 | :101BB0008FFF002801D03D6005E06D1CE268A16840 446 | :101BC0008918A942EDD805494A6902239A434A6116 447 | :101BD00000213170F8BD0000E80200200020024022 448 | :101BE000054901204A69C3071A434A614969002926 449 | :101BF00000DA00207047000000200240F0B51FB45A 450 | :101C0000144C06462078154601280AD00120207081 451 | :101C100000277D20C0006760FFF75AFF002803D02F 452 | :101C200010E0022005B0F0BD012E0DD0294601982C 453 | :101C3000FFF734FF7D20C000FFF74AFF06494A69DD 454 | :101C4000B2434A612770EDE72A46039B0198FFF7EC 455 | :101C500017FFEFE7E80200200020024006490020BD 456 | :101C60004A69002A07DA054A8A60054A8A60496992 457 | :101C7000002900DA01207047002002402301674557 458 | :101C8000AB89EFCD012210B5D2020B49904207D1AA 459 | :101C90000220C863486A002801D001F05BFC10BD37 460 | :101CA000012212039042FAD10420C863886A0028F6 461 | :101CB000F5D001F0EBFF10BD0000002070B5084D1D 462 | :101CC0000446E868204203D0EC60204600F00AF8A1 463 | :101CD0002869204203D02C612046FFF7D3FF70BD56 464 | :101CE00000180240012210B5D2020B49904207D1E0 465 | :101CF0000120C863486A002801D001F02BFC10BD08 466 | :101D0000012212039042FAD10320C863886A002896 467 | :101D1000F5D001F0BBFF10BD00000020F0B500239E 468 | :101D200003249AE02A4601259D402A407ED00E7960 469 | :101D3000B607B60F012E01D0022E16D186682746AF 470 | :101D4000B4465E00B646B7406646BE43B446CF686A 471 | :101D50007646B7406646374387604668AE430D799E 472 | :101D6000ED06ED0F9D40354345600D79ED43AD0720 473 | :101D700008D0C5685F002646BE40B5438E68BE40A9 474 | :101D80002E43C6600D79AD07AD0F022D0ED1DD08D3 475 | :101D9000AD002D18AC462D6A5E07F60E0F27B74032 476 | :101DA000BD430F69B7402F4365462F6205685F004A 477 | :101DB0002646BE40B5430E79B607B60FBE402E4349 478 | :101DC00006604D68AD03AD0F46D09E08264DB600A7 479 | :101DD0007519AC462D6E9E07F60E0F27B740BD4312 480 | :101DE00005273F07B84201D100270FE01F4FB84237 481 | :101DF00001D101270AE01E4FB84201D1022705E0B8 482 | :101E00001C4FB84201D1032700E00527B7402F43FC 483 | :101E1000154D664637662D684E689543F60200D527 484 | :101E20001543114F3D607D68954300E014E04E6816 485 | :101E3000B60200D515437D600B4D80356E684F6846 486 | :101E40009643BF0300D516436E602E684F689643D5 487 | :101E5000FF0300D516432E605B1C0A681546DA4066 488 | :101E600000D05FE7F0BD0000001802400004005001 489 | :101E700000080050000C00500069084000D001200C 490 | :101E80007047002A01D0816170478162704700006D 491 | :101E900001488068704700005000002070B502467D 492 | :101EA00040325378202B1CD11378012B19D00123F9 493 | :101EB000137024245470046825689D4325600468C9 494 | :101EC00025681E03B5432560046825680D43256019 495 | :101ED00000680168194301602020507000201070D4 496 | :101EE00070BD022070BD70B5024640325378202B81 497 | :101EF0001BD11378012B18D00124147024235370A4 498 | :101F000003681D68A5431D6005682B680F2636020F 499 | :101F1000B343090219432960006801682143016045 500 | :101F2000202050700020107070BD022070BD000095 501 | :101F300008B506490A6801231A430A60096819406E 502 | :101F4000009103490A6802430A6008BD401002403C 503 | :101F500000000140406C704770B5040006D0254673 504 | :101F6000403568780026002802D005E0012070BDC9 505 | :101F70002E70204600F0D2F8242068702068016896 506 | :101F80004908490001600F216068090688432168FB 507 | :101F9000086121688A680120C00382438A60E16881 508 | :101FA0000129A16808D02122920211432268916080 509 | :101FB000E168022902D005E00143F7E70121226828 510 | :101FC000C902516021684A680F4B1A434A60216870 511 | :101FD000CA688243CA60616920690843A16909022D 512 | :101FE00008432168C860216AE069084321680860E5 513 | :101FF0002068016801221143016066642020687036 514 | :102000002663AE70002070BD00800002FFB505465B 515 | :1020100004464035687881B0202878D12878012896 516 | :1020200075D001202870FFF733FF0746012200908A 517 | :102030001923D103204600F031FE00283CD1212095 518 | :1020400068701020A8700026666403986062049887 519 | :1020500060856663618D2F48FF2903D9FF222285A1 520 | :1020600000903BE0618D218500903DE02046029983 521 | :1020700000F0CAFD16E000F05EFE00281CD1606A88 522 | :10208000216800788862606A401C6062608D401E32 523 | :102090006085208D401E80B22085618D002901D091 524 | :1020A00000280CD0608D0A9900283A462046E2D1DB 525 | :1020B00000F01BFE00281CD0012005B0F0BD0097E9 526 | :1020C0000022802120460A9B00F0E8FD0028F3D181 527 | :1020D000608DFF2805D9FF222285009601231B066B 528 | :1020E000C4E7608D20850096208D0123C2B25B0677 529 | :1020F000BCE721682020C86121684A68064B1A4065 530 | :102100004A606870AE702E700020D6E7FFE70220AC 531 | :10211000D3E700000020008000E800FE30B58DB05D 532 | :10212000044614216846FEF709F9182105A8FEF7B0 533 | :1021300005F917492068884227D1202000250590FD 534 | :10214000079505A800F0B6F8002801D0FFF77CFC41 535 | :10215000104C616B022001436163616B0295014089 536 | :10216000032000020B9100901220019006200490A1 537 | :10217000039569460848FFF7D1FDE16B0120400552 538 | :102180000143E163E16B01400B910DB030BD0000F4 539 | :1021900000540040001002400004005002488168D2 540 | :1021A00002788918816070475000002010B50848F7 541 | :1021B00000240168821511430160032000F00AF831 542 | :1021C000002801D0012401E000F028F8204610BDCD 543 | :1021D0000020024070B50F4E0024317805460029DA 544 | :1021E00015D07D20C000FEF7BCF801460A48006803 545 | :1021F000FEF7B7F800F0F6FB002808D1042D06D250 546 | :1022000000222946401E00F02BF8756000E00124F2 547 | :10221000204670BD500000205C00002008B5094831 548 | :1022200001680122114301600068104000900548D8 549 | :102230004038C26B01040A43C263C06B084000907F 550 | :1022400008BD000040100240002805DBC106C90E91 551 | :1022500001208840014908607047000000E100E06B 552 | :1022600010B501F04DF910BD10B50F4C21680322D7 553 | :102270005202914301432160C11FFF39FA390ED147 554 | :102280000A480621006848430949FEF76AF8401CDD 555 | :1022900002E0002805D0401E61694905F9D40020FC 556 | :1022A00010BD032010BD0000007000405C00002045 557 | :1022B00040420F00F8B50446006800264D4D8003EB 558 | :1022C00058D54C4800274038C06BC00009D4494855 559 | :1022D0004038C26B01040A43C263C06B0840012747 560 | :1022E000009045480168821511430160FFF7D0FD59 561 | :1022F000009005E0FFF7CCFD0099401A022825D890 562 | :102300003D480068C005F5D5E86903210902084089 563 | :102310000FD0616981420CD0E86903210902EA69A2 564 | :102320008843012109040A43EA61EA698A43EA61B0 565 | :10233000E861C0070FD0FFF7ABFD009008E0FFF7A2 566 | :10234000A7FD0099411A2D48814201D9032609E0D1 567 | :10235000E8698007F3D5E8690321090288436169C8 568 | :102360000843E861002F05D022484038C26B0104C1 569 | :102370008A43C2632078C00705D068696168800815 570 | :102380008000084368612078800606D568690321CB 571 | :1023900009038843A168084368612088400411D577 572 | :1023A000686921698000800808436861012120690B 573 | :1023B0008907884206D10F484038C16801221204BB 574 | :1023C0001143C1602088000512D568690321890383 575 | :1023D0008843E168084368610121E0688903884215 576 | :1023E00006D104484038C168012212041143C1607B 577 | :1023F0003046F8BD401002400070004088130000D5 578 | :10240000F8B50F46060043D04D4D28684007400FF1 579 | :10241000B84213D22868C008C00038432860FFF7CC 580 | :1024200037FD044605E0FFF733FD011B45488142B7 581 | :1024300061D828684007400FB842F4D13068424C58 582 | :1024400081070DD5400704D5A0680721090308437B 583 | :10245000A060A0680F2109028843B1680843A0600A 584 | :102460003078C00732D0706801280AD002280BD01B 585 | :1024700000280FD03449403103280ED0C96989079C 586 | :1024800004E02168890301E021688901002906DB55 587 | :102490000120F8BD21684905F8E7096AEFE7A1685E 588 | :1024A000C908C9000143A160FFF7F2FC009006E0F3 589 | :1024B000FFF7EEFC0099411A224881421BD8A06820 590 | :1024C000382108407168C9008842F1D12868400766 591 | :1024D000400FB84217D91A480168C908C9003943E2 592 | :1024E0000160FFF7D5FC054607E0FFF7D1FC411B73 593 | :1024F0001448814201D90320F8BD11480068400703 594 | :10250000400FB842F1D13078400706D5A0680721C6 595 | :1025100009038843F1680843A06000F031F8A1681E 596 | :102520003C2289091140094A515CC906C90EC840BC 597 | :102530000749086007480068FFF74CFEF8BD000037 598 | :10254000002002408813000000100240743E000882 599 | :102550005C00002054000020064807490068896894 600 | :10256000064A4904490F8900515CC906C90EC84092 601 | :10257000704700005C00002000100240B43E0008DC 602 | :1025800010B5204CA068204A8006400F16D0A068E5 603 | :102590008006410F501001290FD0A1688906490F0C 604 | :1025A000022912D0A0688006400F042823D0A0681A 605 | :1025B0008006400F032821D0002010BD2068012193 606 | :1025C0008004400F8140104612E0E1688B07E1680B 607 | :1025D0009B0F4906490F491C032B00D01046FDF7FD 608 | :1025E000C0FEE1684904490E4843E168490F491CAF 609 | :1025F000FDF7B7FE10BD0120C00310BD7D20000215 610 | :1026000010BD0000001002400024F400F8B50400E2 611 | :102610007ED020783827C007E94D002846D0A8682A 612 | :10262000E96838408907890F102802D008280BD0A4 613 | :1026300001E0032908D001206268000482420AD127 614 | :1026400029680143296015E0286880032ED5606859 615 | :102650000028DDD02AE0052301211B0489049A42C9 616 | :102660002A6802D10A432A60EAE782432A6028687E 617 | :1026700088432860606800280CD0FFF709FC0646F4 618 | :1026800004E0FFF705FC801B642873D828688003EA 619 | :10269000F7D50BE0FFF7FCFB064604E0FFF7F8FB7D 620 | :1026A000801B6428F1D828688003F7D4207880073D 621 | :1026B00069D5A868E96838408A070721920FC902DE 622 | :1026C000102802D0002813D001E0022A10D0E068C0 623 | :1026D000002846D028688843216908432860286874 624 | :1026E000FF21013108432860FFF7D2FB06462CE0AA 625 | :1026F0002A68520502D5E268002A89D06A687F23D9 626 | :102700001B029A4363691B021A436A60002800E0B7 627 | :102710008DE00ED128688843216908432860286825 628 | :1027200001218004400F8140A648FDF71AFEA6490A 629 | :102730000860A6480068FFF74DFD002877D122E029 630 | :10274000FFF7A6FB801B02289FD828684005F7D515 631 | :1027500068687F210902884361690902084368604B 632 | :1027600011E02968FF20013081432960FFF790FBC9 633 | :10277000064605E098E0FFF78BFB801B022884D813 634 | :1027800028684005F7D42078914E00072ED5A86818 635 | :102790008006400F03280AD0A0690028306A16D0AE 636 | :1027A000012108433062FFF773FB07460BE0306AF4 637 | :1027B00080071BD5A06900289FD017E0FFF768FBB2 638 | :1027C000C01B022870D8306A8007F7D50EE0400899 639 | :1027D00040003062FFF75CFB074604E0FFF758FB60 640 | :1027E000C01B022860D8306A8007F7D420784007E1 641 | :1027F0006CD5A86800278006400F042818D0E86B25 642 | :10280000C00008D4E96B012000070143E963E96BCC 643 | :102810000140012700916F480168C90519D401687A 644 | :10282000821511430160FFF733FB00900DE083E058 645 | :10283000F06980074AD5A06800287DD046E0FFF700 646 | :1028400027FB0099401A02282ED862480068C0056C 647 | :10285000F5D5A168012910D004200529F16911D00E 648 | :1028600049084900F161F1698143F161A0680028DC 649 | :1028700016D0FFF70DFB00900EE0F0690121084330 650 | :10288000F061F3E70143F161F7E7FFF701FB00991E 651 | :10289000411A5148814265D8F0698007F5D50EE0AC 652 | :1028A000FFF7F6FA009007E05CE0FFF7F1FA009915 653 | :1028B000411A4948814255D8F0698007F5D4002F64 654 | :1028C00004D0E96B012000078143E963E069002837 655 | :1028D00073D0A9688906490F02294DD00126360612 656 | :1028E0000228286805D0B0432860FFF7D1FA0446D3 657 | :1028F0003AE0B0432860FFF7CBFA074604E0FFF761 658 | :10290000C7FAC01B02282DD828688001F7D4616A55 659 | :10291000206AA26A0843E16A120211430843216B4C 660 | :102920000843E9682D4A11400843E86028683043AD 661 | :102930002860E868012100E03DE009070843E860FD 662 | :10294000FFF7A6FA044604E0FFF7A2FA001B0228EC 663 | :1029500008D828688001F7D52FE0FFF799FA001B07 664 | :10296000022801D90320F8BD28688001F5D4E86861 665 | :102970001B490840E86020E00128F4D0E868226A9A 666 | :102980008107890F914216D17021626A01409142FC 667 | :1029900011D17F21A26A09020140120291420AD19B 668 | :1029A0001F214904E26A0140914204D1400F216B8A 669 | :1029B0004007884201D00120F8BD0020F8BD00008A 670 | :1029C000001002400024F4005C00002054000020AD 671 | :1029D0004010024000700040881300008C80C11F2E 672 | :1029E000FCFFFEEF094910B5401E884201D90120C5 673 | :1029F00010BD074C60610321081F00F081FD00201D 674 | :102A0000A06107202061002010BD0000FFFFFF0033 675 | :102A100000E000E070B5040005D025468035A868C8 676 | :102A2000002802D006E0012070BD00202871204659 677 | :102A300000F026F82420A8602068016849084900B1 678 | :102A40000160204600F0E0FB0128EDD0A06A0028DC 679 | :102A500002D0204600F041FB206841680922D202E2 680 | :102A600091434160206881682A22914381602068F7 681 | :102A70000168012211430160204600F093FB70BD04 682 | :102A800010B586B0044614216846FDF757FC11497D 683 | :102A9000206888421CD11048C26B012149040A43B6 684 | :102AA000C263C26B0A400592426B01210A43426332 685 | :102AB000406B0491084005900C200090022001908A 686 | :102AC000002002900390052069460007FFF726F9D1 687 | :102AD00006B010BD0044004000100240FEE701684F 688 | :102AE0008A69D243920701D400228A620068816910 689 | :102AF000C943C90703D0816901221143816170472D 690 | :102B0000F7B50446006882B0816900262746C906E9 691 | :102B1000403735460092002942DA1021C16131E088 692 | :102B20000398401C2ED0FFF7B3F90099411A03987F 693 | :102B3000814201D8002825D12068416801229203F2 694 | :102B40001140BA788369DB431B0416D401239B032D 695 | :102B5000994212D0202A10D0416819434160FFF7F2 696 | :102B600097F9009009E0FFF793F90099401A1928A6 697 | :102B700003D920200543012604E020688069C04372 698 | :102B80008006F0D4206880698006C00F3043C7D02B 699 | :102B9000002E02D121682020C861042005430126AF 700 | :102BA00021688869C20504D5012215431202CA6151 701 | :102BB0000126410508D508210D432268C901D161CC 702 | :102BC0000126800502D40AE0800506D502200543CF 703 | :102BD00021680002C861012601E0002E0FD02046C6 704 | :102BE000FFF77DFF20684168064A11404160606C34 705 | :102BF00028436064202078700020B8703870304618 706 | :102C000005B0F0BD00E800FE890510B5890D12047D 707 | :102C10001143029C19430268214349005068490846 708 | :102C2000630D034C234398430843506010BD0000DC 709 | :102C3000FF63FF031CB58B00110A0B434004010C1A 710 | :102C40006846037142717D20C0000090022301AAF2 711 | :102C50000948FFF7DBF900280CD008A000F0F2FBD0 712 | :102C60000548FFF777F9042804D008A000F0EAFB34 713 | :102C700001201CBD00201CBDF8000020206932632B 714 | :102C8000206572726F72320D0A0000002069326393 715 | :102C9000206572726F720D0A00000000F8B51D46C3 716 | :102CA00017460E46044609E0681C07D0FFF7F0F807 717 | :102CB0000699401AA8420BD8002D09D020688169D6 718 | :102CC000304688430FD00020B842EDD00020F8BD38 719 | :102CD000616C202001436164403460700020A0706A 720 | :102CE00020700120F8BD0120EEE770B516460D46B4 721 | :102CF00004460FE0324629462046FFF701FF002830 722 | :102D000001D0012070BDFFF7C3F8801BA84208D88E 723 | :102D1000002D06D020688069C0438006EAD40020D8 724 | :102D200070BD616C202001436164403460700020FC 725 | :102D3000A0702070E5E770B516460D46044611E018 726 | :102D4000324629462046FFF7DBFE002801D001204D 727 | :102D500070BD681C06D0FFF79BF8801BA84208D8FE 728 | :102D6000002D06D020688069C0438007E8D4002089 729 | :102D700070BD616C202001436164403460700020AC 730 | :102D8000A0702070E3E70000F0B587B0142168461A 731 | :102D9000FDF7D4FA3C48416B022631434163416B55 732 | :102DA00031400591426B04210A434263426B0A4061 733 | :102DB0000592416B012421434163406B2246204030 734 | :102DC0000590E1033148FFF75CF80520002201215E 735 | :102DD0000007FFF756F8002208212D48FFF751F8A9 736 | :102DE000F72003270025009069460197029528489F 737 | :102DF000FEF794FFA00300906946019702952348CF 738 | :102E0000FEF78CFFE003009001946946039502945D 739 | :102E10001E48FEF783FF05200094019469460007D1 740 | :102E200003950294FEF77AFF052069460007009695 741 | :102E300001950294FEF772FF16480090052069463E 742 | :102E4000019702950007FEF769FFF8020090312014 743 | :102E5000000401900520694602940007FEF75EFF1A 744 | :102E60000820009001946946039502940848FEF7F3 745 | :102E700055FF002211460720FFF7F2F90720FFF760 746 | :102E8000E3F907B0F0BD0000001002400008005058 747 | :102E900000040050F081000010B51548134901608E 748 | :102EA0001449416000218160016141618161012219 749 | :102EB000C161C2600162FFF74FF8002801D0FEF740 750 | :102EC000C3FD00210A48FEF7E9FF002801D0FEF704 751 | :102ED000BBFD00210648FFF706F8002801D0FEF7E9 752 | :102EE000B3FD01200005FFF723F810BD005400409A 753 | :102EF000F8000020290B300010B50D480B49016087 754 | :102F0000E1214902416000218160C160016181616C 755 | :102F1000C16101620C22416242618162FFF77AFD68 756 | :102F2000002801D0FEF790FD10BD000000440040D5 757 | :102F300050010020FEE7704700B585B014216846B7 758 | :102F4000FDF7FCF9012000030090312000040190FE 759 | :102F500001200290052069460007FEF7DFFE0249C6 760 | :102F60000020086205B000BD0000002010B586B04A 761 | :102F700014216846FDF7E2F90120000300901120BA 762 | :102F80000190002003900124052002946946000767 763 | :102F9000FEF7C4FE0148046206B010BD0000002028 764 | :102FA00010B504460648006A002801D1FFF7DEFF8D 765 | :102FB00001210520E2B209030007FEF762FF10BD00 766 | :102FC0000000002000787047F7B504460120C002D9 767 | :102FD00086B01546824248D80004844245D324492D 768 | :102FE000098C4906890EC9020818A0423DD9FEF78E 769 | :102FF00035FE6807400F00F0E1FC401985B260051E 770 | :103000000ED1022102911F21C9066118C90A04913B 771 | :103010000121059103900090694602A8FEF79CFDEE 772 | :103020000026EF081DE00798F1000D182846FDF76F 773 | :1030300087F9E9780002000A090608430290281D72 774 | :10304000FDF77EF90302E8791B0A000603432146D7 775 | :103050000120029AFEF7D2FD002800D10834761C28 776 | :10306000B6B2B742DFD8FEF7BBFD09B0F0BD000035 777 | :10307000C075FF1F704710B5FFF790F810BD30B551 778 | :1030800091B034216846FDF759F9002401200D94D0 779 | :103090000E940F9440021094FFF7E6F80225E80121 780 | :1030A000039000954020059008200A9080030B9023 781 | :1030B0000795000304940C90089509946846FFF75F 782 | :1030C000A5FA07200D900F9402210E9510940DA8DB 783 | :1030D000FFF796F911B030BD704710B5018DC907E3 784 | :1030E00007D001684A6801235B049A43C36A1A4304 785 | :1030F0004A60018D890707D501684A6801231B04CE 786 | :103100009A43036B1A434A60018D490707D501684A 787 | :103110004A6801239B049A43436B1A434A60018D1A 788 | :10312000090707D501684A680123DB039A43836BCB 789 | :103130001A434A60018DC90607D5026891680123C8 790 | :103140001B039943C36B19439160018D890607D511 791 | :1031500001688A6801235B039A43036C1A438A60FF 792 | :10316000018D490612D503685A6801210905446C8E 793 | :103170008A4322435A60426C8A4207D102685168EE 794 | :1031800003235B059943836C19435160018D090644 795 | :1031900007D501684A680123DB04C06C9A430243E7 796 | :1031A0004A6010BDFEB506460025803604463561EE 797 | :1031B000FEF76EFE019020680068124F000709D5E7 798 | :1031C00001210097002249052046019B00F0D0F81C 799 | :1031D00000280DD12068006840070BD50121009719 800 | :1031E000002289052046019B00F0C2F8002801D08A 801 | :1031F0000320FEBD2020B060F060E56625673571D4 802 | :103200000020FEBDFFFFFF01F8B50446806821697C 803 | :10321000E269084361690025114322680843116887 804 | :103220004B4B19400143116020684168032212038F 805 | :103230009143E26811434160A169206A0843216813 806 | :103240008A68444B1A4002438A602068C16A626AF5 807 | :10325000090909011143C1623F492068884211D11F 808 | :103260003E4840698007800F0FD0012806D0022811 809 | :1032700002D003280BD103E0022109E0042107E07A 810 | :10328000082105E03649884201D1002100E01021E3 811 | :103290000120E369C003334A334E344F834227D1C0 812 | :1032A000002906D0022907D0042907D008293FD1D8 813 | :1032B00008E0FFF751F903E0104603E0FFF760F97B 814 | :1032C00000283AD0616A4900715AFDF74AF86168EE 815 | :1032D00040004A088018FDF744F801461039B94209 816 | :1032E00026D82249491C01400007400F084322E02C 817 | :1032F000002906D0022907D0042907D0082917D1B0 818 | :1033000008E0FFF729F903E0104603E0FFF738F97A 819 | :10331000002812D0616A4900715AFDF722F86168ED 820 | :103320004A088018FDF71DF801461039B94201D945 821 | :10333000012502E080B22168C860204601214030AA 822 | :103340004185018500206067A0672846F8BD000020 823 | :10335000F369FFCFFFF4FF11003801404010024035 824 | :10336000004400400024F4005C3E0008EFFF000031 825 | :10337000FFB581B005461746044680350A9E54E0E5 826 | :10338000701C52D0FEF784FD0499401AB0422FD829 827 | :10339000002E2DD020680168490746D5C069C0437A 828 | :1033A000000542D401202168C0020862EFF31080BA 829 | :1033B000012181F3108821680B68FF22A132934319 830 | :1033C0000B6080F31088EFF31080012181F31088E7 831 | :1033D00021688A68520852008A6080F31088202091 832 | :1033E000A860E860286100202871032005B0F0BDC6 833 | :1033F000EFF31080012181F3108821680A68FF2310 834 | :10340000A1339A430A6080F31088EFF31080012102 835 | :1034100081F3108821688A68520852008A6080F31C 836 | :1034200010882020A860E860DDE72068C169029864 837 | :10343000884304D00020B842A2D00020D6E7012063 838 | :10344000F9E700000FB410B503AA0D480299FCF784 839 | :1034500023FF0B48FCF732FF0A49CA695206FCD524 840 | :103460000022074B05E09C5C8C62CC696406FCD5AD 841 | :10347000521C8242F7D310BC08BC04B018470000AD 842 | :10348000E801002000440040F8B5040C8BB2264649 843 | :1034900082B25E43104658430D0C370C36040021AF 844 | :1034A0008019164679416E43370C3604801926463A 845 | :1034B00079416E438919F8BD30B47446641E25788D 846 | :1034C000641CAB4200D21D46635D5B00E31830BC58 847 | :1034D000184700004900CA020243100000D004202F 848 | :1034E0004A0D01D001221043044A490D914201D1F5 849 | :1034F00002210843012800D105207047FF07000082 850 | :103500008307FF22DB0E9A408907090E99400028A5 851 | :1035100008DB830809489B001B1818689043084380 852 | :10352000186070470007000F0838830804489B00A4 853 | :103530001B18D86990430843D861704700E400E045 854 | :1035400000ED00E030380A2801D201207047002049 855 | :1035500070470000F8B57F4C0527606B0121401CC7 856 | :103560006063E26AC902921C380700250126130035 857 | :10357000FFF7A2FF08051112255C74E20D11FEF79A 858 | :103580007BFC012807D1801EE06265632063A66290 859 | :103590006562FFF7D1FCF8BD0746FEF76DFC002819 860 | :1035A00006D1012109033846FEF766FC002803D046 861 | :1035B000606B401C6063F8BDE662A563F8BD06461B 862 | :1035C000FEF75AFC0128F9D101033046FEF754FCFE 863 | :1035D000002826D00220E062207800280AD00128A6 864 | :1035E0000AD0811E4B290CD241005B480818403894 865 | :1035F000808F0EE0208900E0E088FEF7F4F960811A 866 | :1036000012E001464D3914290ED254490818603889 867 | :10361000C07C6081FEF7E7F960812078401C207053 868 | :1036200002E00320E0626580A580F8BDFEF724FC7F 869 | :103630000028FAD1A0880A2804D9A580E762E661AB 870 | :103640006563F8BD0A21091A6089C840C007C00F28 871 | :10365000FFF7A6FCA088401CA080F8BD052000074D 872 | :10366000FEF70AFC0128F8D1010305200007FEF748 873 | :1036700003FC002807D021790A20411A30468840EF 874 | :10368000618808436080A088401C80B2A0800A281E 875 | :10369000E3D92046A5802430E0C0FFF74DFC6088C8 876 | :1036A000FEF7B3F90028D8D060888005800D6080CF 877 | :1036B000216B002908DBE1218900884204D22063C4 878 | :1036C0000220C043E062F8BD4B2804D242002248E9 879 | :1036D000E1888152F8BDFF218900884201D126701E 880 | :1036E000F8BD1F49884201D16670F8BD7F21C9002D 881 | :1036F000884201D14D200AE01949891C884201D134 882 | :10370000022011E01649891E884202D10220207051 883 | :10371000F8BD1349491E884201D12570F8BD1049F2 884 | :10372000C91C884202D104206070F8BD0C49091DF3 885 | :103730008842FAD12563F8BDFEF79EFB0028FAD136 886 | :10374000A088401C80B2A0800928F4D9A580E76237 887 | :10375000F8BD00000000002060000020483E000886 888 | :10376000FB030000F8B54D4D0024E86A4C4E801C68 889 | :1037700010D1E888B04202D90020FFF711FC286B75 890 | :10378000012807D02989814201DC012000E00020C6 891 | :10379000FFF706FCA86C0027401CA864E96C491CD4 892 | :1037A000E9647D210901884208D9286CE8802881D4 893 | :1037B000AF643CA02A6BE96AFFF744FEE888314613 894 | :1037C0003D4E884209D2EA69002A06D000282FD04F 895 | :1037D0000220FF212D31A86107E088420FD9E96955 896 | :1037E00000290CD003203549A861E86CFCF7B9FD2D 897 | :1037F00000291DD1706908214840706118E0E1215D 898 | :103800008900884202D2EA69002A05D088420FD98D 899 | :10381000E869002806D00BE0002809D00120024604 900 | :10382000A86101E00022AF6108213046FEF729FBC4 901 | :1038300000F096FA28466978214D02290CD0214ED5 902 | :10384000032915D0012906D147701F486100641C67 903 | :1038500070524B2CFAD3F8BD032141701BA0FFF727 904 | :10386000F1FD284600F052FA6420FEF763F9F8BD36 905 | :10387000477018A0FFF7E6FD962212492846FFF789 906 | :10388000A3FB6000315A19A0FFF7DCFD0120FEF711 907 | :1038900051F9641C4B2CF4D3F8BD0000000000204B 908 | :1038A000EE0200006F7574206F662072616E6765AE 909 | :1038B0003A25642025640A00000400501027000007 910 | :1038C0000078000860000020FFFF0000457261736F 911 | :1038D00065200A0073617665696E6720746F2066E3 912 | :1038E0006C617368203D3D3D0A000000202C25647A 913 | :1038F00020000000F8B52B4E054600242A4B304628 914 | :1039000022465700DF5BB74209D0AF4201D2EF1B1E 915 | :1039100000E07F1BBFB2B84201D938461446521CA2 916 | :1039200092B24B2AEDD3214E012934D16000195AAD 917 | :10393000A94214D26A1AC01840880A25401A6A435C 918 | :103940000A2195B24843FCF716FD0104090C1FD06B 919 | :103950002846FCF706FD0A214C43001916E0002C0E 920 | :103960001DD0C0184A1B4038C08F0A25081A6A4368 921 | :103970000A2195B24843FCF7FEFC0104090C07D06C 922 | :103980002846FCF7EEFC0A214C43201A84B202E0E0 923 | :103990000A204443A4B2B44201D9044C641E204618 924 | :1039A000F8BD0000FFFF000060000020FF030000E2 925 | :1039B0008001800900BF401EFCD27047014600B55F 926 | :1039C00000200B00FFF778FD08060507090B0D0F17 927 | :1039D0001106072000BD062000BD052000BD042003 928 | :1039E00000BD032000BD022000BD012000BD00007D 929 | :1039F0001CB500248E49601E26460863FEF7D6FBE0 930 | :103A0000FFF73DFBFFF7C0F9FFF746FAFFF774FA3F 931 | :103A1000012208218748FEF734FA05252D070022E8 932 | :103A200001212846FEF72DFA6420FEF783F80122D3 933 | :103A300011462846FEF725FA6420FEF77BF864203D 934 | :103A4000FEF778F87C4865002818FFF7BBFA0702F4 935 | :103A50007948401E2818FFF7B5FA3A4602437748DE 936 | :103A60002146425376A0FFF7EDFC641C4B2CE9DBAA 937 | :103A70007548FFF7E7FC6E4D00276C6CEF80012165 938 | :103A80002F813A46C9037148FEF7FBF901206F62A6 939 | :103A9000A862002208216748FEF7F3F902220721F5 940 | :103AA0002F20FFF7C7F8022207212F20FFF7C2F8C7 941 | :103AB000FFF758FE2CE0FFF755FEA2B201212F20A0 942 | :103AC000FFF7B8F8011E02DD61A0FFF7BBFC686CD0 943 | :103AD000A419844201D8012604E0286C844202D350 944 | :103AE0000026F643044600276420FFF761FF052007 945 | :103AF00002210007FEF7C0F9002811D07F1C0A2F11 946 | :103B0000F2DB052002210007FEF7B6F900280CD0F1 947 | :103B1000052002210007FEF7AFF90128CBD036E0DF 948 | :103B20007D20C000FFF744FFEBE70020A864EC8095 949 | :103B300001262CE0FFF716FEA2B201212F20FFF78D 950 | :103B400079F8011E02DD45A0FFF77CFC686CA41922 951 | :103B5000844201D8012604E0286C844202D3002666 952 | :103B6000F643044600276420FFF722FF05200221C8 953 | :103B70000007FEF781F9012802D07F1C0A2FF2DB33 954 | :103B8000052002210007FEF777F9012807D005205C 955 | :103B900002210007FEF770F9002889D1CAE7002644 956 | :103BA000AE64E86A801C2CD1296B2846012928D1F3 957 | :103BB000C388C168C918C1600269521C0261012A28 958 | :103BC0001FDB2E6168692F46814201DD081A00E083 959 | :103BD000401A04280CDA2448834209D20120FFF756 960 | :103BE000DFF9F98821A07B69FA68FFF72BFC02E076 961 | :103BF0000020FFF7D5F97969F868884200D078612C 962 | :103C0000FE60E88801992E46814202D10099A142C6 963 | :103C10000BD0012100940190FFF76CFE3081224609 964 | :103C2000F18817A0F36AFFF70DFC0026F6433FE783 965 | :103C3000000000200004005001780008600000200F 966 | :103C400025643A25753B2000483E000800080050D6 967 | :103C5000657272303A25642C000000006572723182 968 | :103C60003A25642C00000000EE020000207072650E 969 | :103C700073732025642C25642C25640A0000000041 970 | :103C800025642C25642C25640A000000F8B51E4C20 971 | :103C900000256562E06A052701263F07401C0128D0 972 | :103CA0000FD831033846FEF7E7F8002809D1F102B2 973 | :103CB0003846FEF7E1F8002803D0E562A580666289 974 | :103CC000A562012109033846FEF7D6F8012810D174 975 | :103CD000C1023846FEF7D0F800280AD0E06AC01CBE 976 | :103CE00008D00020A662C0436562E062FFF724F9B5 977 | :103CF0006563F8BD6662A562FFF738F90120C0432D 978 | :103D00006563E062F8BD00000000002010B50446C5 979 | :103D1000114886B084421CD31049098C4906890E8B 980 | :103D2000C9020818A04214D9FDF798FF60050ED10A 981 | :103D3000022100911F21C9066118C90A02910121BF 982 | :103D400001900391049004A96846FDF705FFFDF773 983 | :103D500047FF06B010BD000000780008C075FF1FC7 984 | :103D600010B517480022C16A002903DB436B5B1CB6 985 | :103D7000436300E042634B1C07D08263114C436BEA 986 | :103D8000A34206D9891C07D103E0836B5B1C8363C4 987 | :103D9000F4E74178042912D1427000214263C943FB 988 | :103DA0004262C16201218162FFF7C6F8BFF34F8F03 989 | :103DB00006490548C860BFF34F8F00BFFDE710BD3F 990 | :103DC00000000020881300000400FA0500ED00E068 991 | :103DD00010B500290AD00878002807D00548784493 992 | :103DE000FDF7B6FD002801D0002010BD0248784440 993 | :103DF00010BD0000120200000A02000010B50029E8 994 | :103E00000AD00878002807D005487844FDF7A0FDBF 995 | :103E1000002801D0002010BD0248784410BD0000E9 996 | :103E200002020000FA01000003B40248784484460C 997 | :103E300003BC6047ABCEFFFF03B40248784484461E 998 | :103E400003BC604715D1FFFF56312E3263207061ED 999 | :103E50006E6461706933640A0000000001000200B2 1000 | :103E60000400060008000A000C00100020004000BA 1001 | :103E700080000001000000000000000000000000C1 1002 | :103E80000000000000000000000000000000000032 1003 | :103E9000000000000100000002000000030000001C 1004 | :103EA00004000000060000000700000008000000F9 1005 | :103EB00009000000000000000000000000000000F9 1006 | :103EC00000000000010000000200000003000000EC 1007 | :103ED0000400000000000000000000003031323318 1008 | :103EE000343536373839414243444546403058002E 1009 | :103EF0003031323334353637383961626364656660 1010 | :103F000040307800040000080000000000000002BB 1011 | :103F10000001000010303132333435363738396122 1012 | :103F20006263646566787000303132333435363719 1013 | :103F30003839414243444546585000000240000091 1014 | :103F4000000000A00000000005400000000000C8C4 1015 | :103F5000000000000C4000000000409C0000000039 1016 | :103F6000194000000020BCBE0000000034400000EA 1017 | :103F7000BFC91B8E00000004B5400000504BCFD0DD 1018 | :103F80006607E2CF010000006C4100003E8251AAAA 1019 | :103F9000DFEEA73401000000D9420000DCB5A0E24A 1020 | :103FA0003A301F97FFFFFFFFB4450000FD25A0C872 1021 | :103FB000E9A3C14FFFFFFFFFFF3F000000000080AB 1022 | :103FC00000000000FF3F0000000000800000000033 1023 | :103FD0001C410008000000206000000004010008EF 1024 | :103FE0007C41000860000020080900002001000852 1025 | :103FF0001C00000043000000F8FFFFFF0C00000061 1026 | :104000000E0000000F0000002E0000001001000054 1027 | :1040100043000000F8FFFFFF0040404040404040A8 1028 | :10402000404041414141414040404040404040408B 1029 | :10403000404040404040404040050202020202022F 1030 | :10404000020202020202020202202020202020207E 1031 | :104050002020200202020202020290909090909092 1032 | :104060001010101010101010101010101010101050 1033 | :1040700010101010020202020202888888888888C4 1034 | :1040800008080808080808080808080808080808B0 1035 | :1040900008080808020202024000000000000000B8 1036 | :1040A0000000000000000000000000000000000010 1037 | :1040B0000000000000000000000000000000000000 1038 | :1040C00000000000000000000000000000000000F0 1039 | :1040D00000000000000000000000000000000000E0 1040 | :1040E00000000000000000000000000000000000D0 1041 | :1040F00000000000000000000000000000000000C0 1042 | :1041000000000000000000000000000000000000AF 1043 | :10411000000000000000000000000000000000009F 1044 | :10412000000000000000000000000000000000008F 1045 | :10413000000000000000000000000000000000007F 1046 | :104140000000000000000000FFFFFFFFFFFFFFFF77 1047 | :10415000000000000000000000000000F703000065 1048 | :104160000A00000000000000000000000100000044 1049 | :0C41700004000000000000000024F40027 1050 | :04000005080000C12E 1051 | :00000001FF 1052 | -------------------------------------------------------------------------------- /klipper/BD_sensor.c: -------------------------------------------------------------------------------- 1 | // Code for Bed Distance Sensor 2 | // Mark yue 3 | // This file may be distributed under the terms of the GNU GPLv3 license. 4 | 5 | #include 6 | #include 7 | #include "board/gpio.h" 8 | #include "board/irq.h" 9 | #include "board/misc.h" 10 | #include "command.h" 11 | #include "sched.h" 12 | #include "autoconf.h" // CONFIG_* 13 | #include "basecmd.h" // oid_alloc 14 | #include "board/gpio.h" // gpio_out_write 15 | #include "board/irq.h" // irq_disable 16 | #include "board/misc.h" // timer_is_before 17 | #include "command.h" // DECL_COMMAND 18 | #include "sched.h" // struct timer 19 | #include "stepper.h" // stepper_event 20 | #include "trsync.h" // trsync_add_signal 21 | 22 | #define CMD_READ_DATA 1015 23 | #define CMD_READ_VERSION 1016 24 | #define CMD_START_READ_CALIBRATE_DATA 1017 25 | #define CMD_DISTANCE_MODE 1018 26 | #define CMD_START_CALIBRATE 1019 27 | #define CMD_END_CALIBRATE 1021 28 | #define CMD_REBOOT_SENSOR 1022 29 | #define CMD_SWITCH_MODE 1023 30 | #define DATA_ERROR 1024 31 | 32 | #define CMD_Z_INDEX 1025 33 | #define CMD_CUR_Z 1026 34 | #define CMD_ADJ_Z 1027 35 | #define CMD_DIR_INV 1028 36 | #define CMD_STEP_MM 1029 37 | #define CMD_ZOID 1030 38 | #define CMD_RT_SAMPLE_TIME 1031 39 | #define CMD_RT_RANGE 1032 40 | 41 | 42 | #define BYTE_CHECK_OK 0x01 43 | #define BYTE_CHECK_ERR 0x00 44 | 45 | #define BD_setLow(x) gpio_out_write(x,0) 46 | #define BD_setHigh(x) gpio_out_write(x,1) 47 | 48 | 49 | uint8_t oid_g; 50 | struct endstop { 51 | struct timer time; 52 | uint32_t rest_time, sample_time, nextwake,pin_num; 53 | struct trsync *ts; 54 | uint8_t flags, sample_count, trigger_count, trigger_reason; 55 | struct gpio_in pin; 56 | }; 57 | 58 | enum { ESF_PIN_HIGH=1<<0, ESF_HOMING=1<<1 }; 59 | 60 | uint32_t delay_m = 20, homing_pose = 0; 61 | int sda_pin = -1, scl_pin = -1, z_ofset = 0; 62 | uint16_t BD_Data; 63 | uint16_t BD_read_flag=CMD_DISTANCE_MODE; 64 | int switch_mode = 0; //1:in switch mode 65 | struct gpio_out sda_gpio, scl_gpio; 66 | struct gpio_in sda_gpio_in; 67 | static uint_fast8_t endstop_oversample_event(struct timer *t); 68 | static struct endstop e ; 69 | 70 | int z_index=0; 71 | struct stepper { 72 | struct timer time; 73 | uint32_t interval; 74 | int16_t add; 75 | uint32_t count; 76 | uint32_t next_step_time, step_pulse_ticks; 77 | struct gpio_out step_pin, dir_pin; 78 | uint32_t position; 79 | struct move_queue_head mq; 80 | struct trsync_signal stop_signal; 81 | // gcc (pre v6) does better optimization when uint8_t are bitfields 82 | uint8_t flags : 8; 83 | }; 84 | struct step_adjust{ 85 | uint32_t cur_z; 86 | int adj_z_range; 87 | int invert_dir; 88 | int steps_per_mm; 89 | int step_time; 90 | int zoid;//oid for all the z stepper 91 | }; 92 | 93 | #define NUM_Z_MOTOR 6 94 | struct step_adjust step_adj[NUM_Z_MOTOR];//x,y,z 95 | enum { 96 | SF_LAST_DIR=1<<0, SF_NEXT_DIR=1<<1, SF_INVERT_STEP=1<<2, SF_NEED_RESET=1<<3, 97 | SF_SINGLE_SCHED=1<<4, SF_HAVE_ADD=1<<5 98 | }; 99 | struct endstop bd_tim ; 100 | 101 | int32_t diff_step=0,RT_SAMPLE_TIME=0,adjusted_step=0,RT_RANGE=300;//1000==1mm 102 | 103 | int abs_bd(int a, int b){ 104 | if (a > b) 105 | return a-b; 106 | else 107 | return b-a; 108 | } 109 | extern void 110 | command_config_stepper(uint32_t *args); 111 | void adust_Z_live(uint16_t sensor_z); 112 | void BD_i2c_write(unsigned int addr); 113 | uint16_t BD_i2c_read(void); 114 | void adust_Z_calc(uint16_t sensor_z,struct stepper *s); 115 | 116 | void timer_bd_init(void); 117 | int read_endstop_pin(void); 118 | 119 | 120 | int BD_i2c_init(uint32_t _sda,uint32_t _scl, 121 | uint32_t delays,uint32_t h_pose,int z_adjust,uint32_t enstop_num) 122 | { 123 | int i=0; 124 | e.pin_num = enstop_num; 125 | e.pin = gpio_in_setup(e.pin_num, 1); 126 | sda_pin=_sda; 127 | scl_pin =_scl; 128 | homing_pose = h_pose; 129 | z_ofset = z_adjust; 130 | if (z_ofset > 500) 131 | z_ofset = 0; 132 | if(delays>0) 133 | delay_m=delays; 134 | sda_gpio=gpio_out_setup(sda_pin, 1); 135 | scl_gpio=gpio_out_setup(scl_pin, 1); 136 | 137 | gpio_out_write(sda_gpio, 1); 138 | gpio_out_write(scl_gpio, 1); 139 | for (i=0;i100000000) 147 | RT_SAMPLE_TIME= timer_from_us(11000); 148 | else if(CONFIG_CLOCK_FREQ>60000000) 149 | RT_SAMPLE_TIME= timer_from_us(16000); 150 | else //if(CONFIG_CLOCK_FREQ>60000000) 151 | RT_SAMPLE_TIME= timer_from_us(19000); 152 | return 1; 153 | } 154 | 155 | uint32_t nsecs_to_ticks_bd(uint32_t ns) 156 | { 157 | return ns * (CONFIG_CLOCK_FREQ / 1000000); 158 | } 159 | 160 | void ndelay_bd_c(uint32_t nsecs) 161 | { 162 | // if (CONFIG_MACH_AVR) 163 | // return; 164 | uint32_t end = timer_read_time() + nsecs_to_ticks_bd(nsecs); 165 | while (timer_is_before(timer_read_time(), end)); 166 | // irq_poll(); 167 | } 168 | 169 | void ndelay_bd(uint32_t nsecs) 170 | { 171 | int i=1; 172 | while(i--) 173 | ndelay_bd_c(nsecs); 174 | } 175 | 176 | unsigned short BD_Add_OddEven(unsigned short send_data) 177 | { 178 | unsigned char i; 179 | unsigned char n; 180 | unsigned short out_data; 181 | n =0; 182 | for(i=0;i<10;i++){ 183 | if(((send_data >>i)&0x01) == 0x01){ 184 | n++; 185 | } 186 | } 187 | if((n&0x01) == 0x01){ 188 | out_data = send_data | 0x400; 189 | } 190 | else{ 191 | out_data = send_data | 0x00; 192 | } 193 | return out_data; 194 | } 195 | 196 | unsigned short BD_Check_OddEven(unsigned short rec_data) 197 | { 198 | unsigned char i; 199 | unsigned char n; 200 | unsigned char ret; 201 | n =0; 202 | for(i=0;i<10;i++){ 203 | if(((rec_data >>i)&0x01) == 0x01){ 204 | n++; 205 | } 206 | } 207 | if((rec_data>>10) == (n&0x01)){ 208 | ret = BYTE_CHECK_OK; 209 | } 210 | else{ 211 | ret = BYTE_CHECK_ERR; 212 | } 213 | return ret; 214 | } 215 | 216 | void BD_I2C_start(void) 217 | { 218 | sda_gpio=gpio_out_setup(sda_pin, 1); 219 | scl_gpio=gpio_out_setup(scl_pin, 1); 220 | BD_setHigh(scl_gpio); 221 | BD_setHigh(sda_gpio); 222 | ndelay_bd(delay_m); 223 | BD_setLow(sda_gpio); 224 | ndelay_bd(delay_m); 225 | BD_setLow(scl_gpio); 226 | ndelay_bd(delay_m); 227 | } 228 | 229 | void BD_i2c_stop(void) 230 | { 231 | ndelay_bd(delay_m); 232 | sda_gpio=gpio_out_setup(sda_pin, 1); 233 | BD_setLow(sda_gpio); 234 | ndelay_bd(delay_m); 235 | scl_gpio=gpio_out_setup(scl_pin, 1); 236 | BD_setHigh(scl_gpio); 237 | ndelay_bd(delay_m); 238 | 239 | BD_setHigh(sda_gpio); 240 | ndelay_bd(delay_m); 241 | } 242 | 243 | uint16_t BD_i2c_read(void) 244 | { 245 | uint16_t b = DATA_ERROR; 246 | BD_I2C_start(); 247 | BD_setHigh(sda_gpio); 248 | BD_setHigh(scl_gpio); 249 | ndelay_bd(delay_m); 250 | BD_setLow(scl_gpio); 251 | 252 | ndelay_bd(delay_m); 253 | b = 0; 254 | BD_setHigh(sda_gpio); 255 | sda_gpio_in=gpio_in_setup(sda_pin,0); 256 | for (unsigned char i = 0; i <= 10; i++) { 257 | b <<= 1; 258 | ndelay_bd(delay_m); 259 | BD_setHigh(scl_gpio); 260 | ndelay_bd(delay_m); 261 | // if (gpio_in_read(sda_gpio_in)) 262 | b |= gpio_in_read(sda_gpio_in); 263 | // ndelay_bd(delay_m); 264 | BD_setLow(scl_gpio); 265 | } 266 | BD_i2c_stop(); 267 | if (BD_Check_OddEven(b) && (b & 0x3FF) < 1020){ 268 | b = (b & 0x3FF); 269 | if(BD_read_flag==CMD_DISTANCE_MODE&&(b<1000)){ 270 | b = b - z_ofset; 271 | if(b>DATA_ERROR) 272 | b=0; 273 | } 274 | 275 | } 276 | else 277 | b=DATA_ERROR; 278 | #if 0 279 | sda_gpio_in=gpio_in_setup(sda_pin,0); 280 | b=gpio_in_read(sda_gpio_in)*100; 281 | #endif 282 | return b; 283 | } 284 | 285 | void BD_i2c_write(unsigned int addr) 286 | { 287 | BD_I2C_start(); 288 | //// write 289 | BD_setLow(sda_gpio); 290 | BD_setHigh(scl_gpio); 291 | ndelay_bd(delay_m*2); 292 | BD_setLow(scl_gpio); 293 | addr=BD_Add_OddEven(addr); 294 | ///write address 295 | ndelay_bd(delay_m); 296 | for (int i=10; i >=0; i--) 297 | { 298 | if ((addr>>i)&0x01){ 299 | BD_setHigh(sda_gpio); 300 | } 301 | else 302 | BD_setLow(sda_gpio); 303 | ndelay_bd(delay_m); 304 | BD_setHigh(scl_gpio); 305 | ndelay_bd(delay_m*2); 306 | BD_setLow(scl_gpio); 307 | ndelay_bd(delay_m); 308 | } 309 | BD_i2c_stop(); 310 | } 311 | 312 | struct stepper * 313 | stepper_oid_lookup_bd(uint8_t oid) 314 | { 315 | return oid_lookup(oid, command_config_stepper); 316 | } 317 | 318 | 319 | void adjust_z_move(void) 320 | { 321 | struct stepper *s = stepper_oid_lookup_bd(step_adj[0].zoid); 322 | int dir=0,dir_t=0;//down 323 | if(s->count){ 324 | //diff_step = 0; 325 | return; 326 | } 327 | 328 | if(diff_step>0){ 329 | diff_step--; 330 | adjusted_step--; 331 | } 332 | else{ 333 | diff_step++; 334 | adjusted_step++; 335 | } 336 | 337 | for(int i=0;i0?0:1; 342 | if(step_adj[i].invert_dir==1) 343 | dir=dir?0:1; 344 | dir_t=!!(s->flags&SF_LAST_DIR); 345 | if(dir_t != dir){ 346 | gpio_out_toggle_noirq(s->dir_pin); 347 | } 348 | 349 | } 350 | for(int i=0;istep_pin); 355 | 356 | } 357 | 358 | for(int i=0;i0?0:1; 363 | if(step_adj[i].invert_dir==1) 364 | dir=dir?0:1; 365 | dir_t=!!(s->flags&SF_LAST_DIR); 366 | if(dir_t != dir){ 367 | gpio_out_toggle_noirq(s->dir_pin); 368 | } 369 | 370 | } 371 | 372 | ///limite the adjust range 373 | if(abs_bd(adjusted_step *1000 / step_adj[0].steps_per_mm,0)>RT_RANGE){//>+-0.3mm 374 | //diff_step = 0; 375 | if(adjusted_step>0){ 376 | if (diff_step<0) 377 | diff_step=0; 378 | //output("adjust_z_move adjusted_step=%c steps_per_mm=%c mm=%c ", abs_bd(adjusted_step,0),step_adj[0].steps_per_mm,abs_bd(adjusted_step *1000 / step_adj[0].steps_per_mm,0)); 379 | } 380 | else{ 381 | if (diff_step>0) 382 | diff_step=0; 383 | //output("adjust_z_move adjusted_step=-%c steps_per_mm=%c mm=%c ", abs_bd(adjusted_step,0),step_adj[0].steps_per_mm,abs_bd(adjusted_step *1000 / step_adj[0].steps_per_mm,0)); 384 | 385 | } 386 | return; 387 | } 388 | 389 | } 390 | 391 | #define MAX_Z_PLUSE_TIME 1200 392 | static uint32_t speed_smooth(int32_t adj_len) 393 | { 394 | static int32_t total_len=0,current_inter=MAX_Z_PLUSE_TIME,acc_count=0; 395 | int step_now=abs_bd(diff_step,0); 396 | if (adj_len!=0){ 397 | total_len = abs_bd(adj_len,0); 398 | current_inter=MAX_Z_PLUSE_TIME; 399 | acc_count=0; 400 | } 401 | 402 | if (total_len <=0) 403 | return RT_SAMPLE_TIME; 404 | 405 | if ((total_len-step_now)<(total_len/2)){ 406 | current_inter=current_inter-MAX_Z_PLUSE_TIME/30; 407 | if (current_inter<300){ 408 | current_inter = 300; 409 | return current_inter; 410 | } 411 | acc_count=step_now; 412 | } 413 | else if((total_len-step_now)>(total_len/2)&&(step_nowMAX_Z_PLUSE_TIME) 416 | current_inter = MAX_Z_PLUSE_TIME; 417 | } 418 | return current_inter; 419 | } 420 | 421 | static uint_fast8_t bd_event(struct timer *t) 422 | { 423 | 424 | irq_disable(); 425 | //static uint16_t sensor_z_old = -1; 426 | uint32_t timer_ilde=RT_SAMPLE_TIME; 427 | 428 | if(diff_step){ 429 | adjust_z_move(); 430 | } 431 | else { 432 | if (BD_read_flag == 1018 && (sda_pin >= 0) && (scl_pin >= 0) && 433 | (step_adj[0].zoid&&(step_adj[0].cur_zcount){ 437 | bd_tim.time.waketime =timer_read_time() + timer_ilde; 438 | irq_enable(); 439 | return SF_RESCHEDULE; 440 | } 441 | uint16_t tm=BD_i2c_read(); 442 | if(tm<1023){ 443 | BD_Data=tm; 444 | { 445 | adust_Z_calc(BD_Data,s); 446 | //sensor_z_old = BD_Data; 447 | } 448 | } 449 | else 450 | BD_Data=0; 451 | } 452 | } 453 | 454 | 455 | if(e.sample_count || (step_adj[0].cur_z>step_adj[0].adj_z_range) || step_adj[0].adj_z_range==0) 456 | timer_ilde = timer_ilde*10; 457 | bd_tim.time.waketime =timer_read_time() + timer_ilde; 458 | if(diff_step){ 459 | //bd_tim.time.waketime =timer_read_time()+timer_from_us(300); 460 | bd_tim.time.waketime =timer_read_time()+timer_from_us(speed_smooth(0)); 461 | } 462 | irq_enable(); 463 | return SF_RESCHEDULE; 464 | } 465 | 466 | void timer_bd_init(void) 467 | { 468 | sched_del_timer(&bd_tim.time); 469 | bd_tim.time.waketime = timer_read_time()+1000000; 470 | bd_tim.time.func = bd_event; 471 | sched_add_timer(&bd_tim.time); 472 | adjusted_step=0; 473 | //output("timer_bd_init mcuoid=%c", oid_g); 474 | } 475 | 476 | void timer_bd_uinit(void) 477 | { 478 | sched_del_timer(&bd_tim.time); 479 | //output("timer_bd_uinit mcuoid=%c", oid_g); 480 | } 481 | 482 | void adust_Z_calc(uint16_t sensor_z,struct stepper *s) 483 | { 484 | // BD_Data 485 | static int sensor_z_old=0; 486 | if(step_adj[0].zoid==0 || step_adj[0].adj_z_range<=0 487 | || (step_adj[0].cur_z>step_adj[0].adj_z_range) 488 | || sensor_z>=380||BD_read_flag!=1018){ 489 | 490 | diff_step = 0; 491 | return; 492 | } 493 | 494 | if(s->count){ 495 | //diff_step = 0; 496 | return; 497 | } 498 | int diff_mm = (sensor_z*10 - step_adj[0].cur_z); 499 | diff_step = diff_mm * step_adj[0].steps_per_mm/1000; 500 | //nozzle collision detection prected 501 | if ((sensor_z == sensor_z_old && sensor_z <= 30 && (abs_bd(diff_mm,0)>50)) 502 | ||sensor_z <= 5 ){ 503 | diff_step = -10 * step_adj[0].steps_per_mm/1000; 504 | } 505 | sensor_z = sensor_z_old; 506 | speed_smooth(diff_step); 507 | //output("Z_Move_L mcuoid=%c diff_step=%c sen_z=%c cur_z=%c", oid_g,diff_step>0?diff_step:-diff_step,sensor_z,step_adj[0].cur_z); 508 | // 509 | //////////////////////// 510 | return; 511 | 512 | } 513 | 514 | 515 | void 516 | cmd_RT_Live(uint32_t *args) 517 | { 518 | int cmd=args[1],dat=args[2]; 519 | if(cmd==CMD_Z_INDEX) // 1025 CMD_Z_INDEX 520 | z_index=dat; 521 | else if(cmd==CMD_CUR_Z){ //1026 CMD_CUR_Z 522 | step_adj[0].cur_z=dat; 523 | diff_step = 0; 524 | } 525 | else if(cmd==CMD_ADJ_Z){ //1027 CMD_ADJ_Z 526 | step_adj[z_index].adj_z_range=dat; 527 | if (step_adj[0].adj_z_range<50) 528 | timer_bd_uinit(); 529 | else if(step_adj[0].adj_z_range<=1000)//(step_adj[0].cur_z<=step_adj[z_index].adj_z_range) 530 | timer_bd_init(); 531 | } 532 | else if(cmd==CMD_DIR_INV) //1028 CMD_DIR_INV 533 | step_adj[z_index].invert_dir=dat; 534 | else if(cmd==CMD_STEP_MM){ //1029 CMD_STEP_MM 535 | step_adj[z_index].steps_per_mm=dat; 536 | } 537 | else if(cmd==CMD_ZOID){ //1030 CMD_ZOID 538 | step_adj[z_index].zoid=dat; 539 | } 540 | else if(cmd==CMD_RT_SAMPLE_TIME){ //1031 CMD_SAMPLE_TIME 541 | RT_SAMPLE_TIME= timer_from_us(dat*1000);; 542 | } 543 | else if(cmd==CMD_RT_RANGE){ //1032 CMD_SAMPLE_TIME 544 | RT_RANGE= dat; 545 | } 546 | 547 | } 548 | 549 | void 550 | command_I2C_BD_send(uint32_t *args) 551 | { 552 | unsigned int cmd_c=args[1]; 553 | oid_g=args[0]; 554 | //output("command_I2C_BD_send mcuoid=%c cmd=%c dat=%c", args[0],cmd_c,args[2]); 555 | //only read data 556 | if(cmd_c==CMD_READ_DATA && args[2]==1){ 557 | 558 | BD_Data=BD_i2c_read(); 559 | sendf("I2CBDr oid=%c r=%c", oid_g,BD_Data); 560 | } 561 | else if(cmd_c<1025&& args[2]==0){ 562 | BD_read_flag=cmd_c; 563 | BD_i2c_write(cmd_c); 564 | if(cmd_c>CMD_READ_DATA){ 565 | switch_mode=0; 566 | } 567 | sendf("I2CBDr oid=%c r=%c", oid_g,cmd_c); 568 | } 569 | else if(cmd_c>=1025 && cmd_c<=1032 ){ 570 | BD_read_flag=cmd_c; 571 | switch_mode=0; 572 | cmd_RT_Live(args); 573 | sendf("I2CBDr oid=%c r=%c", oid_g,cmd_c); 574 | } 575 | else if(cmd_c==1033 ){ 576 | if(e.pin_num!=sda_pin) 577 | cmd_c = gpio_in_read(e.pin); 578 | else if (switch_mode == 1){ 579 | cmd_c = gpio_in_read(sda_gpio_in); 580 | } 581 | else 582 | cmd_c = read_endstop_pin(); 583 | 584 | sendf("I2CBDr oid=%c r=%c", oid_g,cmd_c); 585 | } 586 | } 587 | 588 | DECL_COMMAND(command_I2C_BD_send, "I2CBD oid=%c c=%c d=%c"); 589 | 590 | 591 | void 592 | command_config_I2C_BD(uint32_t *args) 593 | { 594 | BD_i2c_init(args[1],args[2],args[3],args[4],args[5],args[6]); 595 | } 596 | DECL_COMMAND(command_config_I2C_BD, 597 | "config_I2C_BD oid=%c sda_pin=%u scl_pin=%u" 598 | " delay=%u h_pos=%u z_adjust=%u estop_pin=%u"); 599 | 600 | int read_endstop_pin(void) 601 | { 602 | uint16_t tm; 603 | tm=BD_i2c_read(); 604 | if(tm 4 | # This file may be distributed under the terms of the GNU GPLv3 license. 5 | import sched 6 | import time 7 | import copy 8 | import chelper 9 | import math 10 | from threading import Timer 11 | from mcu import MCU, MCU_trsync 12 | from . import manual_probe 13 | from . import probe 14 | BD_TIMER = 0.600 15 | TRSYNC_TIMEOUT = 0.025 16 | TRSYNC_SINGLE_MCU_TIMEOUT = 0.250 17 | 18 | CMD_READ_DATA = 1015 19 | CMD_READ_VERSION = 1016 20 | CMD_START_READ_CALIBRATE_DATA = 1017 21 | CMD_DISTANCE_MODE = 1018 22 | CMD_START_CALIBRATE = 1019 23 | CMD_DISTANCE_RAWDATA_TYPE = 1020 24 | CMD_END_CALIBRATE = 1021 25 | CMD_REBOOT_SENSOR = 1022 26 | CMD_SWITCH_MODE = 1023 27 | DATA_ERROR = 1024 28 | CMD_READ_ENDSTOP = 1033 29 | 30 | 31 | # Calculate a move's accel_t, cruise_t, and cruise_v 32 | def calc_move_time(dist, speed, accel): 33 | axis_r = 1. 34 | if dist < 0.: 35 | axis_r = -1. 36 | dist = -dist 37 | if not accel or not dist: 38 | return axis_r, 0., dist / speed, speed 39 | max_cruise_v2 = dist * accel 40 | if max_cruise_v2 < speed ** 2: 41 | speed = math.sqrt(max_cruise_v2) 42 | accel_t = speed / accel 43 | accel_decel_d = accel_t * speed 44 | cruise_t = (dist - accel_decel_d) / speed 45 | return axis_r, accel_t, cruise_t, speed 46 | 47 | # Helper to obtain a single probe measurement 48 | def run_single_probe(probe, gcmd): 49 | probe_session = probe.start_probe_session(gcmd) 50 | probe_session.run_probe(gcmd) 51 | pos = probe_session.pull_probed_results()[0] 52 | probe_session.end_probe_session() 53 | return pos 54 | 55 | # I2C BD_SENSOR 56 | # devices connected to an MCU via an virtual i2c bus(2 any gpio) 57 | 58 | HINT_TIMEOUT = """ 59 | If the probe did not move far enough to trigger, then 60 | consider reducing the Z axis minimum position so the probe 61 | can travel further (the Z minimum position can be negative). 62 | """ 63 | 64 | 65 | class BDPrinterProbe: 66 | def __init__(self, config, mcu_probe): 67 | self.printer = config.get_printer() 68 | self.name = config.get_name() 69 | self.config = config 70 | self.mcu_probe = mcu_probe 71 | self.speed = config.getfloat('speed', 5.0, above=0.) 72 | self.lift_speed = config.getfloat('lift_speed', self.speed, above=0.) 73 | self.x_offset = config.getfloat('x_offset', 0.) 74 | self.y_offset = config.getfloat('y_offset', 0.) 75 | self.z_offset = config.getfloat('z_offset') 76 | self.probe_calibrate_z = 0. 77 | self.multi_probe_pending = False 78 | self.rapid_scan = False 79 | self.last_state = False 80 | self.last_z_result = 0. 81 | self.homing_speed_tmp = 0 82 | self.gcode_move = self.printer.load_object(config, "gcode_move") 83 | # Infer Z position to move to during a probe 84 | if config.has_section('stepper_z'): 85 | zconfig = config.getsection('stepper_z') 86 | self.z_position = zconfig.getfloat('position_min', 0., 87 | note_valid=False) 88 | else: 89 | pconfig = config.getsection('printer') 90 | self.z_position = pconfig.getfloat('minimum_z_position', 0., 91 | note_valid=False) 92 | # Multi-sample support (for improved accuracy) 93 | self.sample_count = config.getint('samples', 1, minval=1) 94 | self.sample_retract_dist = config.getfloat('sample_retract_dist', 5., 95 | above=0.) 96 | self.samples_result = config.getchoice( 97 | 'samples_result', 98 | {'median': 'median', 'average': 'average'}, 99 | 'average' 100 | ) 101 | self.samples_tolerance = config.getfloat('samples_tolerance', 0.100, 102 | minval=0.) 103 | self.samples_retries = config.getint('samples_tolerance_retries', 0, 104 | minval=0) 105 | # Register z_virtual_endstop pin 106 | self.printer.lookup_object('pins').register_chip('probe', self) 107 | 108 | # Register homing event handlers 109 | self.printer.register_event_handler("homing:homing_move_begin", 110 | self._handle_homing_move_begin) 111 | self.printer.register_event_handler("homing:homing_move_end", 112 | self._handle_homing_move_end) 113 | self.printer.register_event_handler("homing:home_rails_begin", 114 | self._handle_home_rails_begin) 115 | self.printer.register_event_handler("homing:home_rails_end", 116 | self._handle_home_rails_end) 117 | self.printer.register_event_handler("gcode:command_error", 118 | self._handle_command_error) 119 | # Register PROBE/QUERY_PROBE commands 120 | self.gcode = self.printer.lookup_object('gcode') 121 | self.gcode.register_command('PROBE', self.cmd_PROBE, 122 | desc=self.cmd_PROBE_help) 123 | self.gcode.register_command('QUERY_PROBE', self.cmd_QUERY_PROBE, 124 | desc=self.cmd_QUERY_PROBE_help) 125 | self.gcode.register_command('PROBE_CALIBRATE', 126 | self.cmd_PROBE_CALIBRATE, 127 | desc=self.cmd_PROBE_CALIBRATE_help) 128 | self.gcode.register_command('PROBE_ACCURACY', self.cmd_PROBE_ACCURACY, 129 | desc=self.cmd_PROBE_ACCURACY_help) 130 | self.gcode.register_command( 131 | 'Z_OFFSET_APPLY_PROBE', 132 | self.cmd_Z_OFFSET_APPLY_PROBE, 133 | desc=self.cmd_Z_OFFSET_APPLY_PROBE_help 134 | ) 135 | gcode = self.printer.lookup_object('gcode') 136 | self.dummy_gcode_cmd = gcode.create_gcode_command("", "", {}) 137 | self.reactor = self.printer.get_reactor() 138 | self.bd_sample_timer = self.reactor.register_timer( 139 | self.scan_sample_event) 140 | 141 | def _probe_state_error(self): 142 | raise self.printer.command_error( 143 | "Internal probe error - start/end probe session mismatch") 144 | 145 | def start_probe_session(self, gcmd): 146 | self._probe_times=[] 147 | if "BED_MESH_CALIBRATE" in gcmd.get_command(): 148 | try: 149 | if self.mcu_probe.no_stop_probe is not None: 150 | self.rapid_scan = True 151 | self.reactor.update_timer(self.bd_sample_timer, self.reactor.NOW) 152 | except AttributeError as e: 153 | gcmd.respond_info("%s" % str(e)) 154 | raise gcmd.error("%s" % str(e)) 155 | if self.multi_probe_pending: 156 | self._probe_state_error() 157 | self.mcu_probe.multi_probe_begin() 158 | self.multi_probe_pending = True 159 | self.mcu_probe.results = [] 160 | return self 161 | 162 | def pull_probed_results(self): 163 | toolhead = self.printer.lookup_object("toolhead") 164 | toolhead.get_last_move_time() 165 | if self.rapid_scan == True: 166 | self.bedmesh = self.printer.lookup_object('bed_mesh', None) 167 | helperc = self.bedmesh.bmc.probe_mgr.probe_helper 168 | while len(self.mcu_probe.results) < len(helperc.probe_points): 169 | toolhead.dwell(0.1) 170 | self.reactor.update_timer(self.bd_sample_timer, self.reactor.NEVER) 171 | self.rapid_scan = False 172 | res = self.mcu_probe.results 173 | self.mcu_probe.results = [] 174 | return res 175 | 176 | def end_probe_session(self): 177 | if not self.multi_probe_pending: 178 | self._probe_state_error() 179 | self.mcu_probe.results = [] 180 | self.multi_probe_pending = False 181 | self.mcu_probe.multi_probe_end() 182 | 183 | def get_probe_params(self, gcmd=None): 184 | if gcmd is None: 185 | gcmd = self.dummy_gcode_cmd 186 | probe_speed = gcmd.get_float("PROBE_SPEED", self.speed, above=0.) 187 | lift_speed = gcmd.get_float("LIFT_SPEED", self.lift_speed, above=0.) 188 | samples = gcmd.get_int("SAMPLES", self.sample_count, minval=1) 189 | sample_retract_dist = gcmd.get_float("SAMPLE_RETRACT_DIST", 190 | self.sample_retract_dist, above=0.) 191 | samples_tolerance = gcmd.get_float("SAMPLES_TOLERANCE", 192 | self.samples_tolerance, minval=0.) 193 | samples_retries = gcmd.get_int("SAMPLES_TOLERANCE_RETRIES", 194 | self.samples_retries, minval=0) 195 | samples_result = gcmd.get("SAMPLES_RESULT", self.samples_result) 196 | return {'probe_speed': probe_speed, 197 | 'lift_speed': lift_speed, 198 | 'samples': samples, 199 | 'sample_retract_dist': sample_retract_dist, 200 | 'samples_tolerance': samples_tolerance, 201 | 'samples_tolerance_retries': samples_retries, 202 | 'samples_result': samples_result} 203 | 204 | 205 | def _handle_homing_move_begin(self, hmove): 206 | if self.mcu_probe in hmove.get_mcu_endstops(): 207 | self.mcu_probe.probe_prepare(hmove) 208 | 209 | def _handle_homing_move_end(self, hmove): 210 | if self.mcu_probe in hmove.get_mcu_endstops(): 211 | self.mcu_probe.probe_finish(hmove) 212 | 213 | def _handle_home_rails_begin(self, homing_state, rails): 214 | endstops = [es for rail in rails for es, name in rail.get_endstops()] 215 | self.mcu_probe.homing = 1 216 | if self.mcu_probe in endstops: 217 | self.mcu_probe.multi_probe_begin() 218 | self.multi_probe_pending = True 219 | for i, rail in enumerate(rails): 220 | if (self.mcu_probe.collision_homing == 1 221 | and rail.homing_retract_dist == 0): 222 | self.homing_speed_tmp = rail.homing_speed 223 | rail.homing_speed = rail.second_homing_speed 224 | self.gcode.respond_info("Homing_speed at %.3f" % (rail.homing_speed)) 225 | 226 | def _handle_home_rails_end(self, homing_state, rails): 227 | endstops = [es for rail in rails for es, name in rail.get_endstops()] 228 | if self.mcu_probe in endstops: 229 | for i, rail in enumerate(rails): 230 | if (self.homing_speed_tmp > rail.homing_speed 231 | and rail.homing_retract_dist == 0): 232 | rail.homing_speed = self.homing_speed_tmp 233 | self.multi_probe_end() 234 | 235 | 236 | def _handle_command_error(self): 237 | try: 238 | self.multi_probe_end() 239 | except: 240 | raise Exception("Multi-probe end") 241 | 242 | def multi_probe_begin(self): 243 | self.mcu_probe.multi_probe_begin() 244 | self.multi_probe_pending = True 245 | 246 | def multi_probe_end(self): 247 | if self.multi_probe_pending: 248 | self.multi_probe_pending = False 249 | self.mcu_probe.multi_probe_end() 250 | 251 | def setup_pin(self, pin_type, pin_params): 252 | if pin_type != 'endstop' or pin_params['pin'] != 'z_virtual_endstop': 253 | raise pins.error("Probe virtual endstop only" 254 | "useful as endstop pin") 255 | if pin_params['invert'] or pin_params['pullup']: 256 | raise pins.error("Can not pullup/invert probe virtual endstop") 257 | return self.mcu_probe 258 | 259 | def get_lift_speed(self, gcmd=None): 260 | if gcmd is not None: 261 | return gcmd.get_float("LIFT_SPEED", self.lift_speed, above=0.) 262 | return self.lift_speed 263 | 264 | def get_offsets(self): 265 | return self.x_offset, self.y_offset, self.z_offset 266 | 267 | def _probe_enstop(self, speed): 268 | toolhead = self.printer.lookup_object('toolhead') 269 | curtime = self.printer.get_reactor().monotonic() 270 | if 'z' not in toolhead.get_status(curtime)['homed_axes']: 271 | raise self.printer.command_error("Must home before probe") 272 | phoming = self.printer.lookup_object('homing') 273 | pos = toolhead.get_position() 274 | pos[2] = self.z_position 275 | try: 276 | epos = phoming.probing_move(self.mcu_probe, pos, speed) 277 | except self.printer.command_error as e: 278 | reason = str(e) 279 | if "Timeout during endstop homing" in reason: 280 | reason += HINT_TIMEOUT 281 | raise self.printer.command_error(reason) 282 | # Allow axis_twist_compensation to update results 283 | self.printer.send_event("probe:update_results", epos) 284 | # add z compensation to probe position 285 | gcode = self.printer.lookup_object('gcode') 286 | gcode.respond_info("probe at %.3f,%.3f is z=%.6f" 287 | % (epos[0], epos[1], epos[2])) 288 | return epos[:3] 289 | 290 | def _probe(self, speed): 291 | self.mcu_probe.homing = 0 292 | if self.mcu_probe.endstop_pin_num != self.mcu_probe.sda_pin_num: 293 | return self._probe_enstop(speed) 294 | toolhead = self.printer.lookup_object('toolhead') 295 | curtime = self.printer.get_reactor().monotonic() 296 | if 'z' not in toolhead.get_status(curtime)['homed_axes']: 297 | raise self.printer.command_error("Must home before probe") 298 | phoming = self.printer.lookup_object('homing') 299 | pos = toolhead.get_position() 300 | self.mcu_probe.reactor.update_timer(self.mcu_probe.bd_update_timer, 301 | self.mcu_probe.reactor.NEVER) 302 | pos[2] = self.z_position 303 | try: 304 | epos = phoming.probing_move(self.mcu_probe, pos, speed) 305 | except self.printer.command_error as e: 306 | reason = str(e) 307 | if "Timeout during endstop homing" in reason: 308 | reason += HINT_TIMEOUT 309 | raise self.printer.command_error(reason) 310 | # self.mcu_probe.adjust_probe() 311 | toolhead.wait_moves() 312 | time.sleep(0.1) 313 | b_value = self.mcu_probe.BD_Sensor_Read(2) 314 | b_value = b_value+self.mcu_probe.BD_Sensor_Read(2) 315 | b_value = b_value+self.mcu_probe.BD_Sensor_Read(2) 316 | b_value = b_value/3 317 | pos_new = toolhead.get_position() 318 | epos[2] = pos_new[2] - b_value + self.mcu_probe.endstop_bdsensor_offset 319 | # Allow axis_twist_compensation to update results 320 | self.printer.send_event("probe:update_results", epos) 321 | self.gcode.respond_info( 322 | "probe at %.3f,%.3f is z=%.6f (pos:%.6f - bd:%.3f)" 323 | % (epos[0], epos[1], epos[2], pos_new[2], b_value) 324 | ) 325 | #self.mcu_probe.homeing = 0 326 | return epos[:3] 327 | 328 | def _move(self, coord, speed): 329 | self.printer.lookup_object('toolhead').manual_move(coord, speed) 330 | 331 | def _calc_mean(self, positions): 332 | count = float(len(positions)) 333 | return [sum([pos[i] for pos in positions]) / count 334 | for i in range(3)] 335 | 336 | def _calc_median(self, positions): 337 | z_sorted = sorted(positions, key=(lambda p: p[2])) 338 | middle = len(positions) // 2 339 | if (len(positions) & 1) == 1: 340 | # odd number of samples 341 | return z_sorted[middle] 342 | # even number of samples 343 | return self._calc_mean(z_sorted[middle - 1:middle + 1]) 344 | 345 | 346 | def _lookup_toolhead_pos(self, pos_time): 347 | toolhead = self.printer.lookup_object('toolhead') 348 | kin = toolhead.get_kinematics() 349 | kin_spos = {s.get_name(): s.mcu_to_commanded_position( 350 | s.get_past_mcu_position(pos_time)) 351 | for s in kin.get_steppers()} 352 | return kin.calc_position(kin_spos) 353 | 354 | def scan_sample_event(self, eventtime): 355 | toolhead = self.printer.lookup_object("toolhead") 356 | while self._probe_times: 357 | pos_time = self._probe_times[0] 358 | while 1: 359 | systime = toolhead.reactor.monotonic() 360 | est_print_time = toolhead.mcu.estimated_print_time(systime) 361 | if est_print_time>=pos_time: 362 | pos = self._lookup_toolhead_pos(pos_time) 363 | intd = self.mcu_probe.BD_Sensor_Read(0) 364 | pos[2] = pos[2] - intd + self.mcu_probe.endstop_bdsensor_offset 365 | self.mcu_probe.results.append(pos) 366 | # Allow axis_twist_compensation to update results 367 | self.printer.send_event("probe:update_results", pos) 368 | # limit the message output to the console else it may take a lot of time 369 | if len(self.mcu_probe.results) < 500: 370 | self.gcode.respond_info("probe at %.3f,%.3f is z=%.6f" 371 | % (pos[0], pos[1], pos[2])) 372 | break 373 | toolhead.reactor.pause(systime + 0.002) 374 | self._probe_times.pop(0) 375 | 376 | return eventtime + 0.005 377 | 378 | 379 | def _scan_lookahead_cb(self, printtime): 380 | self._probe_times.append(printtime) 381 | 382 | def run_probe(self, gcmd): 383 | toolhead = self.printer.lookup_object("toolhead") 384 | if self.rapid_scan == True: 385 | if len(self._probe_times) == 0: 386 | toolhead.wait_moves() 387 | toolhead.register_lookahead_callback(self._scan_lookahead_cb) 388 | return 389 | speed = gcmd.get_float("PROBE_SPEED", self.speed, above=0.) 390 | lift_speed = self.get_lift_speed(gcmd) 391 | 392 | sample_count = gcmd.get_int("SAMPLES", self.sample_count, minval=1) 393 | sample_retract_dist = gcmd.get_float("SAMPLE_RETRACT_DIST", 394 | self.sample_retract_dist, 395 | above=0.) 396 | samples_tolerance = gcmd.get_float("SAMPLES_TOLERANCE", 397 | self.samples_tolerance, minval=0.) 398 | samples_retries = gcmd.get_int("SAMPLES_TOLERANCE_RETRIES", 399 | self.samples_retries, minval=0) 400 | samples_result = gcmd.get("SAMPLES_RESULT", self.samples_result) 401 | 402 | must_notify_multi_probe = not self.multi_probe_pending 403 | if must_notify_multi_probe: 404 | self.start_probe_session(gcmd) 405 | probexy = self.printer.lookup_object('toolhead').get_position()[:2] 406 | retries = 0 407 | positions = [] 408 | toolhead = self.printer.lookup_object('toolhead') 409 | # gcmd.respond_info("speed:%.3f"%speed) 410 | while len(positions) < sample_count: 411 | # Probe position 412 | try: 413 | if ((self.mcu_probe is not None) and 414 | (("BED_MESH_CALIBRATE" in gcmd.get_command()) or 415 | (("QUAD_GANTRY_LEVEL" in gcmd.get_command() or 416 | "Z_TILT_ADJUST" in gcmd.get_command()) 417 | and self.mcu_probe.QGL_Tilt_Probe == 0))): 418 | # pos = self._probe(speed) 419 | toolhead.wait_moves() 420 | time.sleep(0.1) 421 | pos = toolhead.get_position() 422 | intd = self.mcu_probe.BD_Sensor_Read(0) 423 | pos[2] = pos[2] - intd + self.mcu_probe.endstop_bdsensor_offset 424 | self.gcode.respond_info("probe at %.3f,%.3f is z=%.6f" 425 | % (pos[0], pos[1], pos[2])) 426 | # return pos[:3] 427 | positions.append(pos[:3]) 428 | # Check samples tolerance 429 | z_positions = [p[2] for p in positions] 430 | if max(z_positions) - min(z_positions) > samples_tolerance: 431 | if retries >= samples_retries: 432 | raise gcmd.error("Probe samples " 433 | "exceed samples_tolerance") 434 | gcmd.respond_info("Probe samples exceed tolerance." 435 | "Retrying...") 436 | retries += 1 437 | positions = [] 438 | continue 439 | except Exception as e: 440 | gcmd.respond_info("%s" % str(e)) 441 | raise gcmd.error("%s" % str(e)) 442 | # pass 443 | pos = self._probe(speed) 444 | positions.append(pos) 445 | # Check samples tolerance 446 | z_positions = [p[2] for p in positions] 447 | if max(z_positions) - min(z_positions) > samples_tolerance: 448 | if retries >= samples_retries: 449 | raise gcmd.error("Probe samples exceed samples_tolerance") 450 | gcmd.respond_info("Probe samples exceed tolerance. Retrying...") 451 | retries += 1 452 | positions = [] 453 | # Retract 454 | if len(positions) < sample_count: 455 | self._move(probexy + [pos[2] + sample_retract_dist], lift_speed) 456 | if must_notify_multi_probe: 457 | self.multi_probe_end() 458 | # Calculate and return result 459 | if samples_result == 'median': 460 | return self._calc_median(positions) 461 | epos = self._calc_mean(positions) 462 | #epos = calc_probe_z_average(positions, params['samples_result']) 463 | self.mcu_probe.results.append(epos) 464 | 465 | cmd_PROBE_help = "Probe Z-height at current XY position" 466 | 467 | def cmd_PROBE(self, gcmd): 468 | pos = run_single_probe(self, gcmd) 469 | gcmd.respond_info("Result is z=%.6f" % (pos[2],)) 470 | self.last_z_result = pos[2] 471 | 472 | cmd_QUERY_PROBE_help = "Return the status of the z-probe" 473 | 474 | def cmd_QUERY_PROBE(self, gcmd): 475 | toolhead = self.printer.lookup_object('toolhead') 476 | print_time = toolhead.get_last_move_time() 477 | res = self.mcu_probe.query_endstop(print_time) 478 | self.last_state = res 479 | gcmd.respond_info("probe: %s" % (["open", "TRIGGERED"][not not res],)) 480 | 481 | def get_status(self, eventtime): 482 | return {'name': self.name, 483 | 'last_query': self.last_state, 484 | 'last_z_result': self.last_z_result} 485 | 486 | cmd_PROBE_ACCURACY_help = "Probe Z-height accuracy at current XY position" 487 | 488 | def cmd_PROBE_ACCURACY(self, gcmd): 489 | params = self.get_probe_params(gcmd) 490 | speed = gcmd.get_float("PROBE_SPEED", self.speed, above=0.) 491 | lift_speed = self.get_lift_speed(gcmd) 492 | sample_count = gcmd.get_int("SAMPLES", 10, minval=1) 493 | sample_retract_dist = gcmd.get_float("SAMPLE_RETRACT_DIST", 494 | self.sample_retract_dist, above=0.) 495 | toolhead = self.printer.lookup_object('toolhead') 496 | pos = toolhead.get_position() 497 | pos[2] = 1.0 498 | gcmd.respond_info("PROBE_ACCURACY at X:%.3f Y:%.3f Z:%.3f" 499 | " (samples=%d retract=%.3f" 500 | " speed=%.1f lift_speed=%.1f)\n" 501 | % (pos[0], pos[1], pos[2], 502 | sample_count, sample_retract_dist, 503 | speed, lift_speed)) 504 | # Probe bed sample_count times 505 | 506 | # toolhead.manual_move([None, None, pos[2]], speed) 507 | # toolhead.wait_moves() 508 | fo_params = dict(gcmd.get_command_parameters()) 509 | fo_params['SAMPLES'] = '1' 510 | fo_gcmd = self.gcode.create_gcode_command("", "", fo_params) 511 | probe_session = self.start_probe_session(fo_gcmd) 512 | positions = [] 513 | probe_num = 0 514 | while probe_num < sample_count: 515 | # Probe position 516 | probe_session.run_probe(fo_gcmd) 517 | probe_num += 1 518 | # Retract 519 | pos = toolhead.get_position() 520 | liftpos = [None, None, pos[2] + params['sample_retract_dist']] 521 | self._move(liftpos, params['lift_speed']) 522 | positions = probe_session.pull_probed_results() 523 | probe_session.end_probe_session() 524 | 525 | # Calculate maximum, minimum and average values 526 | max_value = max([p[2] for p in positions]) 527 | min_value = min([p[2] for p in positions]) 528 | range_value = max_value - min_value 529 | avg_value = self._calc_mean(positions)[2] 530 | median = self._calc_median(positions)[2] 531 | # calculate the standard deviation 532 | deviation_sum = 0 533 | for i in range(len(positions)): 534 | deviation_sum += pow(positions[i][2] - avg_value, 2.) 535 | sigma = (deviation_sum / len(positions)) ** 0.5 536 | # Show information 537 | gcmd.respond_info( 538 | "probe accuracy results: maximum %.6f, minimum %.6f, range %.6f, " 539 | "average %.6f, median %.6f, standard deviation %.6f" 540 | % (max_value, min_value, range_value, avg_value, median, sigma) 541 | ) 542 | 543 | def probe_calibrate_finalize(self, kin_pos): 544 | if kin_pos is None: 545 | return 546 | 547 | z_offset = self.probe_calibrate_z - kin_pos[2] 548 | self.gcode.respond_info( 549 | "%s: z_offset: %.3f\n" 550 | "The SAVE_CONFIG command will update the printer config file\n" 551 | "with the above and restart the printer." % (self.name, z_offset) 552 | ) 553 | configfile = self.printer.lookup_object('configfile') 554 | configfile.set(self.name, 'z_offset', "%.3f" % z_offset) 555 | 556 | cmd_PROBE_CALIBRATE_help = "Calibrate the probe's z_offset" 557 | 558 | def cmd_PROBE_CALIBRATE(self, gcmd): 559 | manual_probe.verify_no_manual_probe(self.printer) 560 | # Perform initial probe 561 | lift_speed = self.get_lift_speed(gcmd) 562 | params = self.get_probe_params(gcmd) 563 | curpos = run_single_probe(self, gcmd) 564 | # Move away from the bed 565 | self.probe_calibrate_z = curpos[2] 566 | curpos[2] += 5. 567 | self._move(curpos, lift_speed) 568 | # Move the nozzle over the probe point 569 | x_offset, y_offset, z_offset = self.get_offsets() 570 | curpos[0] += x_offset 571 | curpos[1] += y_offset 572 | self._move(curpos, params['probe_speed']) 573 | # Start manual probe 574 | manual_probe.ManualProbeHelper(self.printer, gcmd, 575 | self.probe_calibrate_finalize) 576 | cmd_Z_OFFSET_APPLY_PROBE_help = "Adjust the probe's z_offset" 577 | 578 | def cmd_Z_OFFSET_APPLY_PROBE(self, gcmd): 579 | offset = self.gcode_move.get_status()['homing_origin'].z 580 | configfile = self.printer.lookup_object('configfile') 581 | if offset == 0: 582 | self.gcode.respond_info("Nothing to do: Z Offset is 0") 583 | else: 584 | new_calibrate = self.z_offset - offset 585 | self.gcode.respond_info( 586 | "%s: z_offset: %.3f\n" 587 | "The SAVE_CONFIG command will update the printer config file\n" 588 | "with the above and restart the printer." 589 | % (self.name, new_calibrate)) 590 | configfile.set(self.name, 'z_offset', "%.3f" % (new_calibrate,)) 591 | 592 | 593 | # BDsensor wrapper that enables probe specific features 594 | # set this type of sda_pin 2 as virtual endstop 595 | # add new gcode command M102 for BDsensor 596 | class BDsensorEndstopWrapper: 597 | def __init__(self, config): 598 | self.printer = config.get_printer() 599 | self.printer.register_event_handler('klippy:mcu_identify', self._handle_mcu_identify) 600 | 601 | self.config = config 602 | self.name = config.get_name() 603 | self.g28_cmd = config.get('homing_cmd', 'G28') 604 | self.z_adjust = config.getfloat('z_adjust', 0., minval=-0.3, below=0.3) 605 | self.z_offset = config.getfloat('z_offset', 0., minval=-0.6, maxval=0.6) 606 | self.position_endstop = config.getfloat('position_endstop', 0.7, 607 | minval=0.5, below=2.5) 608 | if self.z_adjust > self.position_endstop: 609 | raise self.printer.command_error("The 'z_adjust' cannot be greater" 610 | " than 'position_endstop' in " 611 | "section [BDsensor]") 612 | if self.z_offset > self.position_endstop: 613 | raise self.printer.command_error("The 'z_offset' cannot be greater" 614 | " than 'position_endstop' in " 615 | "section [BDsensor]") 616 | self.stow_on_each_sample = config.getboolean( 617 | 'deactivate_on_each_sample', True) 618 | self.no_stop_probe = config.get('no_stop_probe', None) 619 | self.collision_homing = config.getint('collision_homing', 0) 620 | self.collision_calibrate = config.getint('collision_calibrate', 0) 621 | self.rt_sample_time = config.getint('rt_sample_time', 0)#ms 622 | self.rt_max_range = config.getfloat('rt_max_range', 0, minval=0) 623 | self.QGL_Tilt_Probe = config.getint('QGL_Tilt_Probe', 1) 624 | self.switch_mode_sample_time = config.getint('SWITCH_MODE_SAMPLE_TIME', 0.006) 625 | self.speed = config.getfloat('speed', 3.0, above=0.) 626 | 627 | gcode_macro = self.printer.load_object(config, 628 | 'gcode_macro') 629 | self.activate_gcode = \ 630 | gcode_macro.load_template(config, 'activate_gcode', '') 631 | self.deactivate_gcode = \ 632 | gcode_macro.load_template(config, 'deactivate_gcode', '') 633 | 634 | self.collision_calibrating = 0 635 | self.switch_mode = 0 636 | self.printer.register_event_handler("stepper_enable:motor_off", 637 | self.event_motor_off) 638 | ppins = self.printer.lookup_object('pins') 639 | # self.mcu_pwm = ppins.setup_pin('pwm', config.get('scl_pin')) 640 | self.bdversion = '' 641 | # Command timing 642 | self.next_cmd_time = self.action_end_time = 0. 643 | pin = config.get('sda_pin') 644 | pin_params = ppins.lookup_pin(pin, can_invert=False, can_pullup=True) 645 | mcu = pin_params['chip'] 646 | self.sda_pin_num = pin_params['pin'] 647 | self.mcu = mcu 648 | # print("b2:%s"%mcu) 649 | pin_s = [] 650 | try: 651 | pin_s = config.get('scl_pin') 652 | except Exception as e: 653 | try: 654 | pin_s = config.get('clk_pin') 655 | except Exception as e: 656 | raise self.printer.command_error("%s" % str(e)) 657 | pass 658 | pin_params = ppins.lookup_pin(pin_s, can_invert=False, can_pullup=True) 659 | mcu = pin_params['chip'] 660 | scl_pin_num = pin_params['pin'] 661 | # print("b3:%s"%mcu) 662 | # pin_params['pullup']=2 663 | # self.mcu_endstop = mcu.setup_pin('endstop', pin_params) 664 | self._invert = pin_params['invert'] 665 | 666 | self.oid = self.mcu.create_oid() 667 | 668 | self.mcu_endstop = self.mcu 669 | self._invert_endstop = self._invert 670 | self.oid_endstop = self.oid 671 | self.endstop_pin_num = self.sda_pin_num 672 | self.endstop_bdsensor_offset = 0 673 | try: 674 | pin = config.get('endstop_pin') 675 | pin_params = ppins.lookup_pin(pin, can_invert=True, can_pullup=True) 676 | self.endstop_pin_num = pin_params['pin'] 677 | self.mcu_endstop = pin_params['chip'] 678 | self._invert_endstop = pin_params['invert'] 679 | if self.mcu_endstop is not self.mcu: 680 | self.oid_endstop = self.mcu_endstop.create_oid() 681 | except Exception as e: 682 | pass 683 | self.cmd_queue = self.mcu.alloc_command_queue() 684 | # Setup iterative solver 685 | ffi_main, ffi_lib = chelper.get_ffi() 686 | self.trapq = ffi_main.gc(ffi_lib.trapq_alloc(), ffi_lib.trapq_free) 687 | self.trapq_append = ffi_lib.trapq_append 688 | self.trapq_finalize_moves = ffi_lib.trapq_finalize_moves 689 | self.stepper_kinematics = ffi_main.gc( 690 | ffi_lib.cartesian_stepper_alloc(b'x'), ffi_lib.free) 691 | 692 | self.config_fmt = ( 693 | "config_I2C_BD oid=%d sda_pin=%s scl_pin=%s delay=%s" 694 | " h_pos=%d z_adjust=%d estop_pin=%s" 695 | % (self.oid, self.sda_pin_num, scl_pin_num, config.get('delay'), self.position_endstop * 100, self.z_adjust * 100,self.endstop_pin_num)) 696 | 697 | self.mcu.add_config_cmd(self.config_fmt) 698 | self.I2C_BD_send_cmd = None 699 | # MCU_BD_I2C_from_config(self.mcu,config) 700 | 701 | # Register commands 702 | self.gcode = self.printer.lookup_object('gcode') 703 | self.width_filament = config.getint('width_filament', 0) 704 | if self.width_filament == 0: 705 | self.gcode.register_command('M102', self.cmd_M102) 706 | self.gcode.register_command('BDSENSOR_VERSION', self.BD_version) 707 | self.gcode.register_command('BDSENSOR_CALIBRATE', self.BD_calibrate) 708 | self.gcode.register_command('BDSENSOR_READ_CALIBRATION', self.BD_read_calibration) 709 | self.gcode.register_command('BDSENSOR_DISTANCE', self.bd_distance) 710 | self.gcode.register_command('BDSENSOR_SET', self.bd_set) 711 | 712 | self.gcode_move = self.printer.load_object(config, "gcode_move") 713 | self.gcode = self.printer.lookup_object('gcode') 714 | self.bedmesh = self.printer.lookup_object('bed_mesh', None) 715 | # Wrappers 716 | self.bd_value = 10.24 717 | self.results = [] 718 | self.finish_home_complete = self.wait_trigger_complete = None 719 | # multi probes state 720 | self.multi = 'OFF' 721 | self.mcu.register_config_callback(self.build_config) 722 | self.adjust_range = 0 723 | self.old_count = 1000 724 | self.homing = 0 725 | self.reactor = self.printer.get_reactor() 726 | self.bd_update_timer = self.reactor.register_timer( 727 | self.bd_update_event) 728 | 729 | self.status_dis = None 730 | # try: 731 | # self.status_dis=self.printer.lookup_object('display_status') 732 | # except Exception as e: 733 | # pass 734 | self._rest_ticks = 0 735 | ffi_main, ffi_lib = chelper.get_ffi() 736 | self._trdispatch = ffi_main.gc(ffi_lib.trdispatch_alloc(), ffi_lib.free) 737 | self._trsyncs = [MCU_trsync(self.mcu_endstop, self._trdispatch)] 738 | self.ncont = 0 739 | self.z_last = 0 740 | self.z_offset_adj = 0 741 | 742 | def get_mcu(self): 743 | return self.mcu 744 | 745 | def build_config(self): 746 | cmd_queue = self._trsyncs[0].get_command_queue() 747 | self.I2C_BD_send_cmd = self.mcu.lookup_query_command( 748 | "I2CBD oid=%c c=%c d=%c", 749 | "I2CBDr oid=%c r=%c", 750 | oid=self.oid, cq=self.cmd_queue) 751 | 752 | self.mcu.register_response(self._handle_BD_Update, 753 | "BD_Update", self.oid) 754 | self.mcu.register_response(self.handle_probe_Update, 755 | "X_probe_Update", self.oid) 756 | self.mcu_endstop.add_config_cmd( 757 | "BDendstop_home oid=%d clock=0 sample_ticks=0 sample_count=0" 758 | " rest_ticks=0 pin_value=0 trsync_oid=0 trigger_reason=0" 759 | " endstop_pin=%s sw=0 sw_val=0" 760 | % (self.oid_endstop, self.endstop_pin_num), on_restart=True) 761 | # Lookup commands 762 | 763 | self._home_cmd = self.mcu_endstop.lookup_command( 764 | "BDendstop_home oid=%c clock=%u sample_ticks=%u sample_count=%c" 765 | " rest_ticks=%u pin_value=%c trsync_oid=%c trigger_reason=%c" 766 | " endstop_pin=%c sw=%c sw_val=%c", 767 | cq=cmd_queue 768 | ) 769 | 770 | def I2C_BD_send(self, cmd, data=0): 771 | data = int(data) 772 | if cmd == CMD_READ_DATA or cmd == CMD_READ_ENDSTOP: 773 | pr = self.I2C_BD_send_cmd.send([self.oid, cmd, data]) 774 | #self.gcode.respond_info(f"{pr}") 775 | return int(pr['r']) 776 | else: 777 | return self.I2C_BD_send_cmd.send([self.oid, cmd, data]) 778 | 779 | def _handle_BD_Update(self, params): 780 | try: 781 | self.bd_value = int(params['distance_val']) / 100.00 782 | if self.status_dis is not None: 783 | strd = str(self.bd_value) + "mm" 784 | if self.bd_value == 10.24: 785 | strd = "BDs:ConnectErr" 786 | if self.bd_value == 3.9: 787 | strd = "BDs:Out Range" 788 | self.status_dis.message = strd 789 | except ValueError as e: 790 | pass 791 | 792 | def handle_probe_Update(self, params): 793 | count = int(params['distance_val'].split(b' ')[1]) 794 | self.old_count = count 795 | try: 796 | self.results.append(int(params['distance_val'].split(b' ')[0])) 797 | except ValueError as e: 798 | pass 799 | 800 | def _force_enable(self, stepper): 801 | self.toolhead = self.printer.lookup_object('toolhead') 802 | print_time = self.toolhead.get_last_move_time() 803 | stepper_enable = self.printer.lookup_object('stepper_enable') 804 | enable = stepper_enable.lookup_enable(stepper.get_name()) 805 | was_enable = enable.is_motor_enabled() 806 | STALL_TIME = 0.100 807 | if not was_enable: 808 | enable.motor_enable(print_time) 809 | self.toolhead.dwell(STALL_TIME) 810 | return was_enable 811 | 812 | def manual_move(self, stepper, dist, speed, accel=0.): 813 | self.toolhead = self.printer.lookup_object('toolhead') 814 | self.toolhead.flush_step_generation() 815 | prev_sk = stepper.set_stepper_kinematics(self.stepper_kinematics) 816 | prev_trapq = stepper.set_trapq(self.trapq) 817 | stepper.set_position((0., 0., 0.)) 818 | axis_r, accel_t, cruise_t, cruise_v = calc_move_time(dist, speed, accel) 819 | print_time = self.toolhead.get_last_move_time() 820 | self.trapq_append( 821 | self.trapq, print_time, accel_t, cruise_t, accel_t, 822 | 0., 0., 0., axis_r, 0., 0., 0., cruise_v, accel 823 | ) 824 | print_time = print_time + accel_t + cruise_t + accel_t 825 | stepper.generate_steps(print_time) 826 | self.trapq_finalize_moves(self.trapq, print_time + 99999.9) 827 | stepper.set_trapq(prev_trapq) 828 | stepper.set_stepper_kinematics(prev_sk) 829 | self.toolhead.note_kinematic_activity(print_time) 830 | self.toolhead.dwell(accel_t + cruise_t + accel_t) 831 | 832 | def bd_set_cur_z(self, hgt, s_log): 833 | if s_log == 1: 834 | self.gcode.respond_info("Curent z:%.2f (gcode_z:%.2f - (z_offset:%.2f - z_offset_adj:%.2f))" % (hgt-(self.z_offset-self.z_offset_adj),hgt,self.z_offset,self.z_offset_adj)) 835 | if (hgt-self.z_offset)<=0: 836 | self.gcode.respond_info("The real_time_adjust is ignored because current z:%.2f (gcode_z:%.2f - (z_offset:%.2f - z_offset_adj:%.2f)) <=0" % (hgt-(self.z_offset-self.z_offset_adj),hgt,self.z_offset,self.z_offset_adj)) 837 | #self.gcode.respond_info("Since current z <0 ") 838 | return; 839 | hgt = hgt-(self.z_offset-self.z_offset_adj) 840 | hgt=int(hgt*1000) 841 | self.I2C_BD_send(1026, hgt) 842 | def event_motor_off(self,print_time): 843 | if self.adjust_range != 0: 844 | self.BD_real_time(0) 845 | 846 | def bd_update_z(self,z): 847 | self.toolhead = self.printer.lookup_object('toolhead') 848 | kin = self.toolhead.get_kinematics() 849 | for stepper in kin.get_steppers(): 850 | if stepper.is_active_axis('z') or stepper.is_active_axis('a') or stepper.is_active_axis('b') or stepper.is_active_axis('c'): 851 | self.bd_set_cur_z(z,1) 852 | break 853 | self.I2C_BD_send(CMD_DISTANCE_MODE) 854 | 855 | def bd_update_event(self, eventtime): 856 | z=self.gcode_move.last_position[2] - self.gcode_move.base_position[2] 857 | if self.homing == 1: 858 | self.reactor.update_timer(self.bd_update_timer, self.reactor.NEVER) 859 | 860 | gcode_move = self.printer.lookup_object("gcode_move") 861 | offset = gcode_move.get_status()['homing_origin'].z 862 | if self.z_offset_adj != offset and offset != 0: 863 | self.z_offset_adj = offset 864 | self.bd_update_z(z) 865 | 866 | if self.z_last != z and self.homing == 0: 867 | self.z_last = z 868 | self.bd_update_z(z) 869 | return eventtime + BD_TIMER 870 | 871 | def cmd_M102(self, gcmd, wait=False): 872 | # self.gcode_que=gcmd 873 | self.process_M102(gcmd) 874 | 875 | def BD_Sensor_Read(self, fore_r): 876 | if fore_r > 0: 877 | self.I2C_BD_send(CMD_DISTANCE_MODE) # prepare to read distance data 878 | intr = self.I2C_BD_send(CMD_READ_DATA, 1) # read data 879 | if intr >= DATA_ERROR: 880 | intr = self.I2C_BD_send(CMD_READ_DATA, 1) 881 | self.bd_value = intr / 100.00 882 | if fore_r == 0: 883 | if self.bd_value >= 10.24: 884 | self.gcode.respond_info("Bed Distance Sensor " 885 | "data error0:%.2f" 886 | % self.bd_value) 887 | raise self.printer.command_error("Bed Distance Sensor " 888 | "data error0:%.2f" 889 | % self.bd_value) 890 | elif self.bd_value > 3.8: 891 | self.gcode.respond_info("Bed Distance Sensor, " 892 | "out of range.:%.2f " 893 | % self.bd_value) 894 | raise self.printer.command_error("Bed Distance Sensor, " 895 | "out of range.:%.2f " 896 | % self.bd_value) 897 | elif fore_r == 2: 898 | if self.bd_value >= 10.24: 899 | self.gcode.respond_info("Bed Distance Sensor " 900 | "data error2:%.2f" 901 | % self.bd_value) 902 | raise self.printer.command_error("Bed Distance Sensor " 903 | "data error2:%.2f" 904 | % self.bd_value) 905 | 906 | return self.bd_value + self.z_offset 907 | 908 | def BD_version(self, gcmd,r_lenght=20): 909 | self.I2C_BD_send(CMD_READ_VERSION) # 1016 // // read sensor version 910 | # self.I2C_BD_send(CMD_READ_VERSION) 911 | self.toolhead = self.printer.lookup_object('toolhead') 912 | ncount1 = 0 913 | x = [] 914 | while 1: 915 | intd = self.I2C_BD_send(CMD_READ_DATA, 1) 916 | if intd > 127: 917 | intd = 127 918 | if intd < 0x20: 919 | intd = 0x20 920 | x.append(intd) 921 | # self.toolhead.dwell(0.1) 922 | ncount1 = ncount1 + 1 923 | if ncount1 >= r_lenght: 924 | self.I2C_BD_send(CMD_DISTANCE_MODE) 925 | res = ''.join(map(chr, x)) 926 | self.bdversion = res 927 | break 928 | self.I2C_BD_send(CMD_DISTANCE_MODE) 929 | #self.I2C_BD_send(CMD_DISTANCE_MODE) 930 | self.switch_mode = 1 931 | if "V1.0 " in self.bdversion \ 932 | or "V1.1 " in self.bdversion \ 933 | or "V1.2 " in self.bdversion: 934 | self.switch_mode = 0 935 | if "V1." in self.bdversion: 936 | self.gcode.respond_info("BDsensorVer:%s,switch_mode=%d," 937 | "collision_homing=%d,collision_cal=%d" 938 | % (self.bdversion, self.switch_mode, 939 | self.collision_homing, 940 | self.collision_calibrate)) 941 | else: 942 | self.gcode.respond_info("No data or corrupt data from BDsensor(%s), " 943 | "Please check connection"%self.bdversion) 944 | 945 | def BD_calibrate(self, gcmd): 946 | if "V1." not in self.bdversion: 947 | self.BD_version(self.gcode,20) 948 | if self.switch_mode == 1 and self.collision_calibrate == 1: 949 | self.collision_calibrating = 1 950 | #gcmd.respond_info("Homing") 951 | self.gcode.run_script_from_command("BED_MESH_CLEAR") 952 | curtime = self.printer.get_reactor().monotonic() 953 | if 'x' not in self.toolhead.get_status(curtime)['homed_axes']: 954 | gstr=self.g28_cmd 955 | gcmd.respond_info("Homing all:"+gstr) 956 | self.gcode.run_script_from_command(gstr) 957 | else: 958 | gstr=self.g28_cmd+" Z" 959 | gcmd.respond_info("Homing z:"+gstr) 960 | self.gcode.run_script_from_command(gstr) 961 | self.gcode.run_script_from_command("G1 Z0") 962 | self.toolhead.wait_moves() 963 | gcmd.respond_info("Calibrating, don't power off the printer") 964 | self.toolhead = self.printer.lookup_object('toolhead') 965 | # kin = self.toolhead.get_kinematics() 966 | self.I2C_BD_send(CMD_DISTANCE_RAWDATA_TYPE) 967 | self.I2C_BD_send(CMD_DISTANCE_RAWDATA_TYPE) 968 | raw_d = self.I2C_BD_send(CMD_READ_DATA, 1) 969 | if raw_d > 600 : 970 | if raw_d == DATA_ERROR: 971 | raise self.printer.command_error("Unable to communicate with bdsensor,%d"%raw_d) 972 | raise self.printer.command_error("BDsensor is too far from the bed:%d"%raw_d) 973 | self.I2C_BD_send(CMD_DISTANCE_MODE) 974 | 975 | self.I2C_BD_send(CMD_START_CALIBRATE) 976 | self.I2C_BD_send(CMD_START_CALIBRATE) 977 | self.gcode.run_script_from_command("SET_KINEMATIC_POSITION Z=0") 978 | curtime = self.printer.get_reactor().monotonic() 979 | if 'z' not in self.toolhead.get_status(curtime)['homed_axes']: 980 | raise self.printer.command_error("make sure [force_move]" 981 | " enable_force_move: true # in the printer.cfg") 982 | self.toolhead.dwell(0.2) 983 | gcmd.respond_info("Please Wait... ") 984 | z_pos = 0 985 | ncount = 0 986 | while 1: 987 | z_pos += 0.1 988 | self.I2C_BD_send((ncount)) 989 | self.I2C_BD_send((ncount)) 990 | self.I2C_BD_send((ncount)) 991 | self.I2C_BD_send((ncount)) 992 | self.toolhead.dwell(0.2) 993 | # self.gcode.run_script_from_command("G91") 994 | # self.gcode.run_script_from_command("G1 Z+0.1 F1500") 995 | # self.gcode.run_script_from_command("G90") 996 | self.toolhead.manual_move([None, None, z_pos], 2) 997 | self.toolhead.wait_moves() 998 | self.toolhead.dwell(0.2) 999 | ncount = ncount + 1 1000 | if ncount >= 40: 1001 | self.I2C_BD_send(CMD_END_CALIBRATE) 1002 | self.toolhead.dwell(1) 1003 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1004 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1005 | self.toolhead.dwell(1) 1006 | self.BD_read_calibration(gcmd) 1007 | gcmd.respond_info("Calibrate Finished!") 1008 | #gcmd.respond_info("You can send command " 1009 | # "BDSENSOR_READ_CALIBRATION " 1010 | # "to check the calibration data") 1011 | self.z_adjust = 0 1012 | #configfile = self.printer.lookup_object('configfile') 1013 | #configfile.set(self.name, 'z_adjust', "0.0") 1014 | break 1015 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1016 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1017 | self.collision_calibrating = 0 1018 | #self.toolhead.dwell(1) 1019 | #self.BD_read_calibration(gcmd) 1020 | def BD_read_calibration(self, gcmd): 1021 | self.I2C_BD_send(CMD_START_READ_CALIBRATE_DATA) # tart read raw calibrate data 1022 | self.I2C_BD_send(CMD_START_READ_CALIBRATE_DATA) 1023 | self.toolhead = self.printer.lookup_object('toolhead') 1024 | ncount1 = 0 1025 | while 1: 1026 | intd = self.I2C_BD_send(CMD_READ_DATA, 1) 1027 | gcmd.respond_info("%d at %.1fmm"%(intd,ncount1/10.0)) 1028 | if ncount1 <= 3 and intd > 500: 1029 | gcmd.respond_raw("BDSensor mounted too high!" 1030 | "0.4mm to 2.4mm from BED at" 1031 | "zero position is recommended") 1032 | # break 1033 | if intd < 45: 1034 | gcmd.respond_raw("BDSensor mounted too close! please mount" 1035 | "the BDsensor 0.2~0.4mm higher") 1036 | # break 1037 | self.toolhead.dwell(0.03) 1038 | ncount1 = ncount1 + 1 1039 | if ncount1 >= 40: 1040 | break 1041 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1042 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1043 | 1044 | def bd_distance(self, gcmd): 1045 | self.bd_value = self.BD_Sensor_Read(1) 1046 | strd = str(self.bd_value) + "mm" 1047 | if self.bd_value == 10.24: 1048 | strd = "BDsensor:Connection Error or not calibrated" 1049 | elif self.bd_value >= 3.9: 1050 | strd = "BDsensor:Out of measure Range or too close to the bed" 1051 | gcmd.respond_raw(strd) 1052 | try: 1053 | self.status_dis = self.printer.lookup_object('display_status') 1054 | self.status_dis.message = strd 1055 | except Exception as e: 1056 | pass 1057 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1058 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1059 | 1060 | def bd_set(self, gcmd): 1061 | cmd_bd = 0.0 1062 | cmd_bd = gcmd.get_float('Z_ADJUST', None) 1063 | if cmd_bd is not None: 1064 | gcmd.respond_info("z_adjust:%f, recommend to move the nozzle " 1065 | "close to bed and calibrate again the BDsensor" 1066 | "instead of chang z_adjust" % cmd_bd) 1067 | if cmd_bd >= 0.3: 1068 | cmd_bd = 0.29 1069 | gcmd.respond_info("it has been set to the max value 0.29") 1070 | elif cmd_bd <= -0.3: 1071 | cmd_bd = -0.29 1072 | gcmd.respond_info("it has been set to the min value -0.29") 1073 | self.z_adjust = cmd_bd 1074 | configfile = self.printer.lookup_object('configfile') 1075 | configfile.set(self.name, 'z_adjust', "%.3f" % cmd_bd) 1076 | gcmd.respond_info("The SAVE_CONFIG command will update" 1077 | "the printer config") 1078 | return 1079 | 1080 | cmd_bd = gcmd.get_float('REAL_TIME_HEIGHT', None) 1081 | if cmd_bd is not None: 1082 | self.BD_real_time(cmd_bd) 1083 | return 1084 | 1085 | cmd_bd = gcmd.get_int('NO_STOP_PROBE', None) 1086 | if cmd_bd is not None: 1087 | configfile = self.printer.lookup_object('configfile') 1088 | configfile.set(self.name, 'no_stop_probe', "%d" % cmd_bd) 1089 | gcmd.respond_info("no_stop_probe is setted:%d The SAVE_CONFIG" 1090 | "command will update the printer config", cmd_bd) 1091 | return 1092 | 1093 | cmd_bd = gcmd.get_float('QGL_TILT_PROBE', None) 1094 | if cmd_bd is not None: 1095 | self.QGL_Tilt_Probe = cmd_bd 1096 | self.gcode.respond_info("QGL_Tilt_Probe:%d"%self.QGL_Tilt_Probe) 1097 | return 1098 | 1099 | cmd_bd = gcmd.get_float('COLLISION_HOMING', None) 1100 | if cmd_bd is not None: 1101 | self.collision_homing = cmd_bd 1102 | return 1103 | cmd_bd = gcmd.get_float('COLLISION_CALIBRATING', None) 1104 | if cmd_bd is not None: 1105 | self.collision_calibrating = cmd_bd 1106 | return 1107 | cmd_bd = gcmd.get_float('POSITION_ENDSTOP', None) 1108 | if cmd_bd is not None: 1109 | self.position_endstop = cmd_bd 1110 | return 1111 | 1112 | def BD_real_time(self, bd_height): 1113 | if bd_height >= 3.0: 1114 | bd_height = 3 1115 | elif bd_height < 0.0: 1116 | bd_height = 0 1117 | self.gcode.respond_info("Real time leveling height:%.2f ( %.2f - z_offset:%.2f ) "%(bd_height-self.z_offset,bd_height,self.z_offset)) 1118 | 1119 | if bd_height == 0: 1120 | self.adjust_range = 0 1121 | else: 1122 | bd_height = bd_height-self.z_offset 1123 | self.adjust_range = int((bd_height+0.01)*1000) 1124 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1125 | self.toolhead = self.printer.lookup_object('toolhead') 1126 | kin = self.toolhead.get_kinematics() 1127 | z_index = 0 1128 | for stepper in kin.get_steppers(): 1129 | if stepper.is_active_axis('z') or stepper.is_active_axis('a') or stepper.is_active_axis('b') or stepper.is_active_axis('c'): 1130 | steps_per_mm = 1.0/stepper.get_step_dist() 1131 | #z = self.gcode_move.last_position[2] 1132 | z=self.gcode_move.last_position[2] - self.gcode_move.base_position[2] 1133 | #stepper._query_mcu_position() 1134 | invert_dir, orig_invert_dir = stepper.get_dir_inverted() 1135 | #z = int(z*1000) 1136 | self.I2C_BD_send(1025, z_index) 1137 | #self.I2C_BD_send(1026, z) 1138 | self.bd_set_cur_z(z,0) 1139 | self.I2C_BD_send(1027, self.adjust_range) 1140 | self.I2C_BD_send(1028, orig_invert_dir) 1141 | self.I2C_BD_send(1029, steps_per_mm) 1142 | if self.rt_sample_time > 0: 1143 | self.I2C_BD_send(1031, self.rt_sample_time) 1144 | if self.rt_max_range > 0: 1145 | self.I2C_BD_send(1032, self.rt_max_range*1000) 1146 | self.I2C_BD_send(1030, stepper.get_oid()) 1147 | z_index = z_index + 1 1148 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1149 | if self.adjust_range == 0: 1150 | self.reactor.update_timer(self.bd_update_timer, self.reactor.NEVER) 1151 | else: 1152 | self.reactor.update_timer(self.bd_update_timer, self.reactor.NOW) 1153 | 1154 | def process_M102(self, gcmd): 1155 | self.process_m102 = 1 1156 | cmd_bd = 0 1157 | try: 1158 | cmd_bd = gcmd.get_int('S', None) 1159 | except Exception as e: 1160 | pass 1161 | return 1162 | self.toolhead = self.printer.lookup_object('toolhead') 1163 | if cmd_bd == -6: 1164 | self.BD_calibrate(gcmd) 1165 | elif cmd_bd == -5: 1166 | self.BD_read_calibration(gcmd) 1167 | elif cmd_bd == -1: 1168 | self.BD_version(gcmd,20) 1169 | elif cmd_bd == -2: # gcode M102 S-2 read distance data 1170 | self.bd_distance(gcmd) 1171 | elif cmd_bd == -7: 1172 | self.I2C_BD_send(CMD_DISTANCE_RAWDATA_TYPE) 1173 | strd = "Raw data:" + str(self.I2C_BD_send(CMD_READ_DATA, 1)) 1174 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1175 | self.bd_value = self.BD_Sensor_Read(1) 1176 | strd = strd + ", Then we can calculate the distance by comparing to the calibration data:"+str(self.bd_value) + "mm" 1177 | gcmd.respond_raw(strd) 1178 | return 1179 | elif cmd_bd == -8: 1180 | self.I2C_BD_send(CMD_REBOOT_SENSOR) 1181 | elif cmd_bd == -9: 1182 | self.I2C_BD_send(CMD_SWITCH_MODE) 1183 | self.I2C_BD_send(str(int(self.position_endstop * 100))) 1184 | self.gcode.respond_info("in switch mode, the endstop position is" 1185 | "%.3f mm" % self.position_endstop) 1186 | return 1187 | else: 1188 | return 1189 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1190 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1191 | # self.process_m102=0 1192 | 1193 | def _handle_mcu_identify(self): 1194 | kin = self.printer.lookup_object('toolhead').get_kinematics() 1195 | for stepper in kin.get_steppers(): 1196 | if stepper.is_active_axis('z'): 1197 | self.add_stepper(stepper) 1198 | 1199 | def raise_probe(self): 1200 | return 1201 | 1202 | def lower_probe(self): 1203 | return 1204 | 1205 | def query_endstop(self, print_time): 1206 | params = 1 1207 | params = self.I2C_BD_send(CMD_READ_ENDSTOP) 1208 | if self.endstop_pin_num != self.sda_pin_num and self._invert_endstop: 1209 | if params == 0: 1210 | params = 1 1211 | else : 1212 | params = 0 1213 | self.gcode.respond_info("params:%d" % params) 1214 | return params 1215 | 1216 | def add_stepper(self, stepper): 1217 | trsyncs = {trsync.get_mcu(): trsync for trsync in self._trsyncs} 1218 | trsync = trsyncs.get(stepper.get_mcu()) 1219 | if trsync is None: 1220 | trsync = MCU_trsync(stepper.get_mcu(), self._trdispatch) 1221 | self._trsyncs.append(trsync) 1222 | trsync.add_stepper(stepper) 1223 | # Check for unsupported multi-mcu shared stepper rails 1224 | sname = stepper.get_name() 1225 | if sname.startswith('stepper_'): 1226 | for ot in self._trsyncs: 1227 | for s in ot.get_steppers(): 1228 | if ot is not trsync and s.get_name().startswith(sname[:9]): 1229 | cerror = self.mcu.get_printer().config_error 1230 | raise cerror("Multi-mcu homing not supported on" 1231 | " multi-mcu shared axis") 1232 | 1233 | def get_steppers(self): 1234 | return [s for trsync in self._trsyncs for s in trsync.get_steppers()] 1235 | 1236 | def home_start(self, print_time, sample_time, sample_count, rest_time, 1237 | triggered=True): 1238 | collision_value = int(self.position_endstop * 100) 1239 | if "V1." not in self.bdversion: 1240 | self.BD_version(self.gcode,5) 1241 | #self.homing = 1 1242 | if self.switch_mode == 1: 1243 | #self.I2C_BD_send(CMD_SWITCH_MODE) 1244 | sample_time = self.switch_mode_sample_time 1245 | sample_count = 2 1246 | if self.homing == 1 and (self.collision_homing == 1 1247 | or self.collision_calibrating == 1): 1248 | #self.I2C_BD_send(1) 1249 | collision_value = 1 1250 | #else: 1251 | # self.I2C_BD_send(int(self.position_endstop * 100)) 1252 | #self.gcode.respond_info("home_pos:%s" % str(int(self.position_endstop * 100))) 1253 | # time.sleep(0.01) 1254 | else: 1255 | sample_time = .03 1256 | sample_count = 1 1257 | 1258 | clock = self.mcu_endstop.print_time_to_clock(print_time) 1259 | rest_ticks = \ 1260 | self.mcu_endstop.print_time_to_clock(print_time+rest_time) - clock 1261 | self._rest_ticks = rest_ticks 1262 | reactor = self.mcu_endstop.get_printer().get_reactor() 1263 | self.wait_trigger_complete = \ 1264 | reactor.register_callback(self.wait_for_trigger) 1265 | self.trigger_completion = reactor.completion() 1266 | expire_timeout = TRSYNC_TIMEOUT 1267 | if len(self._trsyncs) == 1: 1268 | expire_timeout = TRSYNC_SINGLE_MCU_TIMEOUT 1269 | for i, trsync in enumerate(self._trsyncs): 1270 | report_offset = float(i) / len(self._trsyncs) 1271 | trsync.start(print_time, report_offset, 1272 | self.trigger_completion, expire_timeout) 1273 | self.etrsync = self._trsyncs[0] 1274 | ffi_main, ffi_lib = chelper.get_ffi() 1275 | ffi_lib.trdispatch_start(self._trdispatch, 1276 | self.etrsync.REASON_HOST_REQUEST) 1277 | 1278 | self._home_cmd.send( 1279 | [ 1280 | self.oid_endstop, 1281 | clock, 1282 | self.mcu_endstop.seconds_to_clock(sample_time), 1283 | sample_count, 1284 | self.mcu_endstop.seconds_to_clock(sample_time), 1285 | triggered ^ self._invert_endstop, 1286 | self.etrsync.get_oid(), 1287 | self.etrsync.REASON_ENDSTOP_HIT, 1288 | self.endstop_pin_num, 1289 | self.switch_mode,collision_value 1290 | ], 1291 | reqclock=clock 1292 | ) 1293 | self.finish_home_complete = self.trigger_completion 1294 | return self.trigger_completion 1295 | 1296 | def wait_for_trigger(self, eventtime): 1297 | self.trigger_completion.wait() 1298 | if self.multi == 'OFF': 1299 | self.raise_probe() 1300 | 1301 | def home_wait(self, home_end_time): 1302 | etrsync = self._trsyncs[0] 1303 | etrsync.set_home_end_time(home_end_time) 1304 | if self.mcu_endstop.is_fileoutput(): 1305 | self.trigger_completion.complete(True) 1306 | self.trigger_completion.wait() 1307 | self._home_cmd.send([self.oid_endstop, 0, 0, 0, 0, 0, 0, 0, 1308 | self.endstop_pin_num,0,0]) 1309 | ffi_main, ffi_lib = chelper.get_ffi() 1310 | ffi_lib.trdispatch_stop(self._trdispatch) 1311 | res = [trsync.stop() for trsync in self._trsyncs] 1312 | if any([r == etrsync.REASON_COMMS_TIMEOUT for r in res]): 1313 | return -1. 1314 | if res[0] != etrsync.REASON_ENDSTOP_HIT: 1315 | return 0. 1316 | if self.mcu_endstop.is_fileoutput(): 1317 | return home_end_time 1318 | return home_end_time 1319 | 1320 | def multi_probe_begin(self): 1321 | # self.BD_Sensor_Read(2)# check the if the BDsensor is working 1322 | curtime = self.printer.get_reactor().monotonic() 1323 | self.toolhead = self.printer.lookup_object('toolhead') 1324 | kin_status = self.toolhead.get_kinematics().get_status(curtime) 1325 | if 'z' not in kin_status['homed_axes'] and self.endstop_pin_num == self.sda_pin_num: 1326 | #self.gcode.respond_info("Check bd sensor") 1327 | self.BD_Sensor_Read(2)# check the if the BDsensor is working 1328 | if self.stow_on_each_sample: 1329 | return 1330 | self.multi = 'FIRST' 1331 | 1332 | def adjust_probe_up(self, up_steps, second_steps, logd): 1333 | homepos = self.toolhead.get_position() 1334 | time.sleep(0.03) 1335 | intr = self.I2C_BD_send(CMD_READ_DATA, 1) 1336 | intr_old = intr 1337 | if intr > 720: 1338 | self.gcode.respond_info("warning: triggered in air, %d"%intr) 1339 | pos_old = homepos[2] 1340 | while 1: 1341 | homepos[2] += up_steps 1342 | self.toolhead.manual_move([None, None, homepos[2]], 2) 1343 | self.toolhead.wait_moves() 1344 | time.sleep(0.05) 1345 | raw_d = self.I2C_BD_send(CMD_READ_DATA, 1) 1346 | if (raw_d - intr) >= (up_steps*100*2): 1347 | if second_steps == 0: 1348 | break 1349 | pos_old_1 = homepos[2] 1350 | homepos[2] -= 0.1 # (up_steps*1.5) 1351 | self.toolhead.manual_move([None, None, homepos[2]], 2) 1352 | self.toolhead.wait_moves() 1353 | intr = raw_d 1354 | while 1: 1355 | homepos[2] += second_steps 1356 | self.toolhead.manual_move([None, None, homepos[2]], 1) 1357 | self.toolhead.wait_moves() 1358 | time.sleep(0.05) 1359 | raw_d = self.I2C_BD_send(CMD_READ_DATA, 1) 1360 | #homepos_n = self.toolhead.get_position() 1361 | if (raw_d - intr) >= (second_steps*100*2) or homepos[2] >= pos_old_1: 1362 | if logd == 1: 1363 | temp = 0 1364 | try: 1365 | pheaters = self.printer.lookup_object('heaters') 1366 | heaters = pheaters.lookup_heater('heater_bed') 1367 | temp, target = heaters.get_temp(self.printer.get_reactor().monotonic()) 1368 | except Exception as e: 1369 | pass 1370 | self.gcode.respond_info("Raw data:%d at 0 mm, BDsensor to bed: %.4f mm, Bed: %.1fC, z_offset: %.3f" 1371 | % (raw_d,raw_d*0.004,temp,self.z_offset)) 1372 | return homepos[2]-pos_old,raw_d-intr_old 1373 | break 1374 | intr = raw_d 1375 | break 1376 | intr = raw_d 1377 | return 0,0 1378 | 1379 | def adjust_probe_down(self, down_steps): 1380 | homepos = self.toolhead.get_position() 1381 | raw_d = self.I2C_BD_send(CMD_READ_DATA, 1) 1382 | intr = raw_d 1383 | homepos[2] = 5 1384 | self.toolhead.set_position(homepos) 1385 | while 1: 1386 | homepos[2] -= down_steps 1387 | self.toolhead.manual_move([None, None, homepos[2]], 2) 1388 | self.toolhead.wait_moves() 1389 | time.sleep(0.05) 1390 | raw_d = self.I2C_BD_send(CMD_READ_DATA, 1) 1391 | #self.gcode.respond_info(" %d "%raw_d) 1392 | if (intr - raw_d) < down_steps*100 and raw_d < 500: 1393 | #self.gcode.respond_info(" stop at %d "%raw_d) 1394 | break; 1395 | intr = raw_d 1396 | 1397 | 1398 | 1399 | 1400 | def adjust_probe(self): 1401 | self.toolhead = self.printer.lookup_object('toolhead') 1402 | homepos = self.toolhead.get_position() 1403 | self.I2C_BD_send(CMD_DISTANCE_RAWDATA_TYPE) 1404 | self.I2C_BD_send(CMD_DISTANCE_RAWDATA_TYPE) 1405 | adj_z,adj_raw = self.adjust_probe_up(0.1,0,1) 1406 | #if adj_z <= 0.15: # and adj_raw >= 6: 1407 | 1408 | self.adjust_probe_down(0.1) 1409 | adj_z,adj_raw = self.adjust_probe_up(0.05,0.01,0) 1410 | 1411 | self.adjust_probe_down(0.05) 1412 | adj_z,adj_raw = self.adjust_probe_up(0.05,0.005,1) 1413 | 1414 | #if adj_z <= 0.1: # and adj_raw >= 6: 1415 | # self.gcode.respond_info("re-adjusting") 1416 | # self.adjust_probe_down(0.1) 1417 | # adj_z,adj_raw = self.adjust_probe_up(0.05,0.01,1) 1418 | self.bd_value = self.BD_Sensor_Read(2) 1419 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1420 | 1421 | def multi_probe_end(self): 1422 | self.toolhead = self.printer.lookup_object('toolhead') 1423 | homepos = self.toolhead.get_position() 1424 | if self.endstop_pin_num == self.sda_pin_num: 1425 | 1426 | if self.switch_mode == 1 \ 1427 | and self.homing == 1 \ 1428 | and (self.collision_homing == 1 1429 | or self.collision_calibrating == 1): 1430 | 1431 | self.adjust_probe() 1432 | #homepos[2] = 0 1433 | if self.collision_calibrating != 1: 1434 | # homepos[2] = 0 + self.z_offset + 0.5 1435 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1436 | homepos = self.toolhead.get_position() 1437 | homepos[2] +=0.5 1438 | self.toolhead.manual_move([None, None, homepos[2]], 2) 1439 | self.toolhead.wait_moves() 1440 | self.bd_value = self.BD_Sensor_Read(2) 1441 | time.sleep(0.1) 1442 | homepos[2] -=0.5 1443 | self.toolhead.manual_move([None, None, homepos[2]], 2) 1444 | self.toolhead.wait_moves() 1445 | self.gcode.respond_info("bd_value at %.3f mm" % self.bd_value) 1446 | if abs(self.bd_value-self.z_offset-0.5)>0.05: 1447 | self.gcode.respond_info("Detect the plate changed or others, the BD sensor needs recalibration %.3f" % (self.bd_value-0.5)) 1448 | # self.toolhead.manual_move([None, None, homepos[2]+10], 2) 1449 | self.gcode.run_script_from_command("M102 S-6") 1450 | return 1451 | 1452 | homepos[2] = 0 + self.z_offset 1453 | else: 1454 | homepos[2] = 0 1455 | self.toolhead.set_position(homepos) 1456 | elif self.homing == 1: 1457 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1458 | time.sleep(0.1) 1459 | #self.gcode.respond_info("multi_probe_end") 1460 | self.bd_value = self.BD_Sensor_Read(2) 1461 | if self.bd_value > (self.position_endstop + 2): 1462 | self.gcode.respond_info("triggered at %.3f mm" % self.bd_value) 1463 | self.I2C_BD_send(CMD_REBOOT_SENSOR) 1464 | time.sleep(0.9) 1465 | self.bd_value = self.BD_Sensor_Read(2) 1466 | if self.bd_value > (self.position_endstop + 0.7): 1467 | raise self.printer.command_error("Home z failed! " 1468 | "the triggered at " 1469 | "%.3fmm" % self.bd_value) 1470 | if self.bd_value <= 0: 1471 | self.gcode.respond_info("warning:triggered at 0mm") 1472 | # time.sleep(0.1) 1473 | self.endstop_bdsensor_offset = 0 1474 | if self.sda_pin_num is not self.endstop_pin_num: 1475 | self.endstop_bdsensor_offset = homepos[2] - self.bd_value 1476 | self.gcode.respond_info("offset of endstop to bdsensor %.3fmm" 1477 | % self.endstop_bdsensor_offset) 1478 | else: 1479 | homepos[2] = self.bd_value 1480 | self.toolhead.set_position(homepos) 1481 | # time.sleep(0.1) 1482 | #self.gcode.respond_info("Z triggered at %.3f mm,auto adjusted." 1483 | # % self.bd_value) 1484 | self.homing = 0 1485 | if self.stow_on_each_sample: 1486 | return 1487 | self.raise_probe() 1488 | self.multi = 'OFF' 1489 | 1490 | def probe_prepare(self, hmove): 1491 | if self.multi == 'OFF' or self.multi == 'FIRST': 1492 | self.lower_probe() 1493 | if self.multi == 'FIRST': 1494 | self.multi = 'ON' 1495 | 1496 | def probe_finish(self, hmove): 1497 | self.I2C_BD_send(CMD_DISTANCE_MODE) 1498 | if self.multi == 'OFF': 1499 | self.raise_probe() 1500 | 1501 | def get_position_endstop(self): 1502 | # print("BD get_position_endstop") 1503 | return self.position_endstop 1504 | 1505 | 1506 | def load_config(config): 1507 | bdl = BDsensorEndstopWrapper(config) 1508 | config.get_printer().add_object('probe', BDPrinterProbe(config, bdl)) 1509 | return bdl 1510 | -------------------------------------------------------------------------------- /klipper/README.md: -------------------------------------------------------------------------------- 1 | 2 | Installing for Klipper 3 | 4 | https://github.com/markniu/Bed_Distance_sensor/wiki/Installing-for-Klipper 5 | 6 | -------------------------------------------------------------------------------- /klipper/install_BDsensor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOME_DIR="${HOME}/klipper" 4 | 5 | if [ -d "$1" ] ; then 6 | 7 | echo "$1" 8 | HOME_DIR=""$1"/klipper" 9 | fi 10 | 11 | BDDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 12 | 13 | 14 | 15 | if [ ! -d "$HOME_DIR" ] ; then 16 | echo "" 17 | echo "path error doesn't exist in "$HOME_DIR"" 18 | echo "" 19 | echo "BDsensor path: "$BDDIR"" 20 | echo "" 21 | echo "usage example:./install_BDsensor.sh /home/pi or ./install_BDsensor.sh /home/mks " 22 | echo "Error!!" 23 | exit 1 24 | fi 25 | 26 | echo "klipper path: "$HOME_DIR"" 27 | echo "BDsensor path: "$BDDIR"" 28 | echo "" 29 | 30 | echo "linking BDsensor.py to klippy." 31 | 32 | if [ -e "${HOME_DIR}/klippy/extras/BDsensor.py" ]; then 33 | rm "${HOME_DIR}/klippy/extras/BDsensor.py" 34 | fi 35 | ln -s "${BDDIR}/BDsensor.py" "${HOME_DIR}/klippy/extras/BDsensor.py" 36 | 37 | echo "linking BD_sensor.c to klipper." 38 | 39 | if [ -e "${HOME_DIR}/src/BD_sensor.c" ]; then 40 | rm "${HOME_DIR}/src/BD_sensor.c" 41 | fi 42 | ln -s "${BDDIR}/BD_sensor.c" "${HOME_DIR}/src/BD_sensor.c" 43 | 44 | if [ -e "${HOME_DIR}/make_with_bdsensor.sh" ]; then 45 | rm "${HOME_DIR}/make_with_bdsensor.sh" 46 | fi 47 | ln -s "${BDDIR}/make_with_bdsensor.sh" "${HOME_DIR}/make_with_bdsensor.sh" 48 | 49 | if ! grep -q "BD_sensor.c" "${HOME_DIR}/src/Makefile"; then 50 | echo "src-y += BD_sensor.c " >> "${HOME_DIR}/src/Makefile" 51 | fi 52 | 53 | 54 | if ! grep -q "klippy/extras/BDsensor.py" "${HOME_DIR}/.git/info/exclude"; then 55 | echo "klippy/extras/BDsensor.py" >> "${HOME_DIR}/.git/info/exclude" 56 | fi 57 | if ! grep -q "src/BD_sensor.c" "${HOME_DIR}/.git/info/exclude"; then 58 | echo "src/BD_sensor.c" >> "${HOME_DIR}/.git/info/exclude" 59 | fi 60 | 61 | if ! grep -q "make_with_bdsensor.sh" "${HOME_DIR}/.git/info/exclude"; then 62 | echo "make_with_bdsensor.sh" >> "${HOME_DIR}/.git/info/exclude" 63 | fi 64 | 65 | 66 | echo "" 67 | echo "Install Bed Distance Sensor successful " 68 | echo "" 69 | echo "you can compile the klipper firmware now, for example:" 70 | echo "" 71 | echo "cd ~/klipper/" 72 | echo "make menuconfig" 73 | echo "./make_with_bdsensor.sh" 74 | echo "" 75 | echo "then flash firmware into the mcu that the bdsensor connected" 76 | echo "please note:here we run ./make_with_bdsensor.sh instead of make to compile " 77 | echo "happy printing!" -------------------------------------------------------------------------------- /klipper/make_with_bdsensor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "compiling BD_sensor.c into the klipper firmware" 3 | sed -i '/BD_sensor/d' src/Makefile;echo "src-y += BD_sensor.c" >> src/Makefile 4 | sed 's/--dirty//g' "./scripts/buildcommands.py" -i 5 | 6 | make 7 | 8 | sed -i '/BD_sensor/d' src/Makefile 9 | git checkout src/Makefile 10 | git checkout ./scripts/buildcommands.py -------------------------------------------------------------------------------- /klipper/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOME_DIR="${HOME}/klipper" 4 | 5 | if [ -d "$1" ] ; then 6 | 7 | echo "$1" 8 | HOME_DIR=""$1"/klipper" 9 | fi 10 | 11 | BDDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 12 | 13 | echo "klipper path: "$HOME_DIR"" 14 | echo "BDsensor path: "$BDDIR"" 15 | echo "" 16 | 17 | echo "delete BDsensor.py and BD_sensor.c from klipper" 18 | 19 | rm "${HOME_DIR}/klippy/extras/BDsensor.py" 20 | rm "${HOME_DIR}/src/BD_sensor.c" 21 | rm "${HOME_DIR}/make_with_bdsensor.sh" 22 | 23 | sed -i '/src-y += BD_sensor.c/d' "${HOME_DIR}/src/Makefile" 24 | 25 | cd "$HOME_DIR" 26 | git checkout "${HOME_DIR}/scripts/buildcommands.py" 27 | 28 | echo "" 29 | echo "Uninstalled Bed Distance Sensor successful :) " 30 | echo "" 31 | -------------------------------------------------------------------------------- /klipper/width_bdsensor.py: -------------------------------------------------------------------------------- 1 | # Bed leveling sensor BDsensor(Bed Distance sensor) 2 | # https://github.com/markniu/Bed_Distance_sensor 3 | # Copyright (C) 2023 Mark yue 4 | # This file may be distributed under the terms of the GNU GPLv3 license. 5 | import sched 6 | import time 7 | import copy 8 | import chelper 9 | import math 10 | from threading import Timer 11 | from mcu import MCU, MCU_trsync 12 | from . import filament_switch_sensor 13 | 14 | from . import BDsensor 15 | 16 | class WidthSensorBDsensor: 17 | def __init__(self, config): 18 | self.printer = config.get_printer() 19 | self.config = config 20 | self.reactor = self.printer.get_reactor() 21 | self.gcode = self.printer.lookup_object('gcode') 22 | self.width_filament = config.getint('width_filament', 0) 23 | self.MEASUREMENT_INTERVAL_MM=config.getint('measurement_interval',10) 24 | self.use_current_dia_while_delay = config.getboolean( 25 | 'use_current_dia_while_delay', False) 26 | self.nominal_filament_dia = config.getfloat( 27 | 'default_nominal_filament_diameter', 1.75) 28 | self.measurement_delay = config.getfloat('measurement_delay', 1) 29 | self.measurement_max_difference = config.getfloat('max_difference', 0.2) 30 | self.max_diameter = (self.nominal_filament_dia 31 | + self.measurement_max_difference) 32 | self.min_diameter = (self.nominal_filament_dia 33 | - self.measurement_max_difference) 34 | self.diameter =self.nominal_filament_dia 35 | self.is_active =config.getboolean('enable', False) 36 | self.runout_dia_min = config.getfloat('min_diameter', 1.0) 37 | self.runout_dia_max = config.getfloat('max_diameter', self.max_diameter) 38 | self.is_active = False #config.getboolean('enable', False) 39 | self.extrude_factor_update_timer = self.reactor.register_timer( 40 | self.extrude_factor_update_event) 41 | self.gcode.register_command('ENABLE_FILAMENT_WIDTH_SENSOR', 42 | self.cmd_enable) 43 | self.gcode.register_command('DISABLE_FILAMENT_WIDTH_SENSOR', 44 | self.cmd_disable) 45 | self.gcode.register_command('CLEAR_FILAMENT_WIDTH_SENSOR', 46 | self.cmd_clear) 47 | self.printer.register_event_handler("klippy:ready", self.handle_ready) 48 | self.zero_pose = 0 49 | self.filament_array = [] 50 | self.runout_helper = filament_switch_sensor.RunoutHelper(config) 51 | self.bdsensor = BDsensor.BDsensorEndstopWrapper(config) 52 | # Initialization 53 | def handle_ready(self): 54 | # Load printer objects 55 | self.toolhead = self.printer.lookup_object('toolhead') 56 | 57 | # Start extrude factor update timer 58 | self.reactor.update_timer(self.extrude_factor_update_timer, 59 | self.reactor.NOW) 60 | 61 | def cmd_clear(self, gcmd): 62 | self.zero_pose = 0 63 | 64 | def cmd_enable(self, gcmd): 65 | response = "Filament width sensor Turned On" 66 | if self.is_active: 67 | response = "Filament width sensor is already On" 68 | else: 69 | self.is_active = True 70 | # Start extrude factor update timer 71 | self.reactor.update_timer(self.extrude_factor_update_timer, 72 | self.reactor.NOW) 73 | gcmd.respond_info(response) 74 | 75 | def cmd_disable(self, gcmd): 76 | response = "Filament width sensor Turned Off" 77 | if not self.is_active: 78 | response = "Filament width sensor is already Off" 79 | else: 80 | self.is_active = False 81 | # Stop extrude factor update timer 82 | self.reactor.update_timer(self.extrude_factor_update_timer, 83 | self.reactor.NEVER) 84 | # Clear filament array 85 | self.filament_array = [] 86 | # Set extrude multiplier to 100% 87 | self.gcode.run_script_from_command("M221 S100") 88 | gcmd.respond_info(response) 89 | 90 | def update_filament_array(self, last_epos): 91 | 92 | self.diameter = self.bdsensor.BD_Sensor_Read(2) 93 | self.gcode.respond_info("Filament width:%.3f" % 94 | (self.diameter)) 95 | # Fill array 96 | if len(self.filament_array) > 0: 97 | # Get last reading position in array & calculate next 98 | # reading position 99 | next_reading_position = (self.filament_array[-1][0] + 100 | self.MEASUREMENT_INTERVAL_MM) 101 | if next_reading_position <= (last_epos + self.measurement_delay): 102 | self.filament_array.append([last_epos + self.measurement_delay, 103 | self.diameter]) 104 | if self.is_log: 105 | self.gcode.respond_info("Filament width:%.3f" % 106 | (self.diameter)) 107 | 108 | else: 109 | # add first item to array 110 | self.filament_array.append([self.measurement_delay + last_epos, 111 | self.diameter]) 112 | self.firstExtruderUpdatePosition = (self.measurement_delay 113 | + last_epos) 114 | 115 | def extrude_factor_update_event(self, eventtime): 116 | # Update extrude factor 117 | pos = self.toolhead.get_position() 118 | last_epos = pos[3] 119 | # Update filament array for lastFilamentWidthReading 120 | self.update_filament_array(last_epos) 121 | # Check runout 122 | self.runout_helper.note_filament_present( 123 | self.runout_dia_min <= self.diameter <= self.runout_dia_max) 124 | # Does filament exists 125 | if self.diameter > 0.5: 126 | if len(self.filament_array) > 0: 127 | # Get first position in filament array 128 | pending_position = self.filament_array[0][0] 129 | if pending_position <= last_epos: 130 | # Get first item in filament_array queue 131 | item = self.filament_array.pop(0) 132 | self.filament_width = item[1] 133 | else: 134 | if ((self.use_current_dia_while_delay) 135 | and (self.firstExtruderUpdatePosition 136 | == pending_position)): 137 | self.filament_width = self.diameter 138 | elif self.firstExtruderUpdatePosition == pending_position: 139 | self.filament_width = self.nominal_filament_dia 140 | if ((self.filament_width <= self.max_diameter) 141 | and (self.filament_width >= self.min_diameter)): 142 | percentage = round(self.nominal_filament_dia ** 2 143 | / self.filament_width ** 2 * 100) 144 | self.gcode.run_script("M221 S" + str(percentage)) 145 | else: 146 | self.gcode.run_script("M221 S100") 147 | else: 148 | self.gcode.run_script("M221 S100") 149 | self.filament_array = [] 150 | 151 | if self.is_active: 152 | return eventtime + 1 153 | else: 154 | return self.reactor.NEVER 155 | 156 | 157 | def load_config(config): 158 | return WidthSensorBDsensor(config) 159 | -------------------------------------------------------------------------------- /marlin/BD_Config_Tool_Marlin.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markniu/Bed_Distance_sensor/b26df49227211dd9fd1c7db5b6027894aeaf9edc/marlin/BD_Config_Tool_Marlin.zip -------------------------------------------------------------------------------- /marlin/README.md: -------------------------------------------------------------------------------- 1 | Install marlin 2 | 3 | https://github.com/markniu/Bed_Distance_sensor/wiki/Installing-Bed-Distance-Sensor 4 | 5 | example: https://drive.google.com/drive/folders/13poitJhHradERgTLGtSDJb0zpuyNYHZY?usp=sharing 6 | 7 | --------------------------------------------------------------------------------