@@ -166,5 +166,170 @@ export const i2cCategory: BlockCategory = {
166166 } ;
167167 }
168168 } ,
169+ {
170+ id : 'i2c_write_bytes' ,
171+ name : 'I2C Write Bytes' ,
172+ color : '#0ea5e9' ,
173+ icon : '📦' ,
174+ category : 'i2c' ,
175+ description : 'เขียนหลาย byte ไปยัง I2C bus ในคราวเดียว โดยระบุค่า HEX แต่ละ byte คั่นด้วยช่องว่าง เช่น "00 1A FF"' ,
176+ inputs : [ { id : 'in' , type : 'input' , label : '➜' , dataType : 'any' , description : 'รับสายลำดับการทำงานจากบล็อกก่อนหน้า' } ] ,
177+ outputs : [ { id : 'out' , type : 'output' , label : '➜' , dataType : 'void' , description : 'ส่งสายลำดับการทำงานต่อไป' } ] ,
178+ params : [
179+ {
180+ id : 'bytes' ,
181+ type : 'text' ,
182+ label : 'Bytes (HEX, space-separated)' ,
183+ default : '00 1A FF' ,
184+ description : 'ค่า HEX แต่ละ byte คั่นด้วยช่องว่าง เช่น 00 1A FF'
185+ } ,
186+ ] ,
187+ toCode ( { pad, block, safeId, params, registerPreprocessor } ) {
188+ registerPreprocessor ( '#include <Wire.h>' ) ;
189+ const id = safeId ( block . id ) ;
190+ const raw = ( params . bytes ?? '00' ) . trim ( ) ;
191+ // Parse each token as hex byte, filter invalid ones
192+ const tokens = raw . split ( / \s + / ) . filter ( ( t ) => / ^ [ 0 - 9 a - f A - F ] { 1 , 2 } $ / . test ( t ) ) ;
193+ const byteList = tokens . map ( ( t ) => `0x${ t . toUpperCase ( ) . padStart ( 2 , '0' ) } ` ) . join ( ', ' ) ;
194+ const len = tokens . length || 1 ;
195+ return {
196+ parts : [
197+ [
198+ `${ pad } { byte _buf_${ id } [${ len } ] = {${ byteList } };` ,
199+ `${ pad } Wire.write(_buf_${ id } , ${ len } ); }` ,
200+ ] ,
201+ { portId : 'out' , depthDelta : 0 }
202+ ]
203+ } ;
204+ }
205+ } ,
206+ {
207+ id : 'i2c_mem_write' ,
208+ name : 'I2C Mem Write' ,
209+ color : '#0ea5e9' ,
210+ icon : '📝' ,
211+ category : 'i2c' ,
212+ description : 'เขียนข้อมูลไปยัง register address ภายใน I2C device (beginTransmission → write reg → write data → endTransmission)' ,
213+ inputs : [
214+ { id : 'in' , type : 'input' , label : '➜' , dataType : 'any' , description : 'รับสายลำดับการทำงานจากบล็อกก่อนหน้า' } ,
215+ { id : 'value' , type : 'input' , label : 'Value' , dataType : 'int' , description : 'ค่าที่ต้องการเขียน' } ,
216+ ] ,
217+ outputs : [ { id : 'out' , type : 'output' , label : '➜' , dataType : 'void' , description : 'ส่งสายลำดับการทำงานต่อไป' } ] ,
218+ params : [
219+ { id : 'address' , type : 'number' , label : 'Device Addr (hex)' , default : '0x68' , description : 'I2C address ของ device' } ,
220+ { id : 'reg' , type : 'number' , label : 'Register (hex)' , default : '0x00' , description : 'register address ภายใน device' } ,
221+ { id : 'value' , type : 'number' , label : 'Value (dec)' , default : '0' , description : 'ค่าที่จะเขียน (ใช้เมื่อไม่มีบล็อกต่อเข้ามา)' } ,
222+ {
223+ id : 'size' , type : 'option' , label : 'Size' ,
224+ options : [
225+ { label : 'Byte (1 byte)' , value : 'byte' } ,
226+ { label : 'Word (2 bytes)' , value : 'word' } ,
227+ ] ,
228+ description : 'ขนาดข้อมูลที่จะเขียน'
229+ } ,
230+ {
231+ id : 'endian' , type : 'option' , label : 'Endian' ,
232+ options : [
233+ { label : 'Big-endian (BE)' , value : 'BE' } ,
234+ { label : 'Little-endian (LE).' , value : 'LE' } ,
235+ ] ,
236+ description : 'ลำดับไบต์ Big-endian / Little-endian'
237+ } ,
238+ ] ,
239+ toCode ( { pad, params, resolveInput, registerPreprocessor } ) {
240+ registerPreprocessor ( '#include <Wire.h>' ) ;
241+ const addr = params . address ?? '0x68' ;
242+ const reg = params . reg ?? '0x00' ;
243+ const size = params . size ?? 'byte' ;
244+ const endian = params . endian ?? 'BE' ;
245+ const value = resolveInput ( 'value' ) ?? params . value ?? '0' ;
246+ const lines : string [ ] = [
247+ `${ pad } Wire.beginTransmission(${ addr } );` ,
248+ `${ pad } Wire.write(${ reg } );` ,
249+ ] ;
250+ if ( size === 'word' ) {
251+ if ( endian === 'BE' ) {
252+ lines . push ( `${ pad } Wire.write((uint8_t)((${ value } ) >> 8));` ) ;
253+ lines . push ( `${ pad } Wire.write((uint8_t)((${ value } ) & 0xFF));` ) ;
254+ } else {
255+ lines . push ( `${ pad } Wire.write((uint8_t)((${ value } ) & 0xFF));` ) ;
256+ lines . push ( `${ pad } Wire.write((uint8_t)((${ value } ) >> 8));` ) ;
257+ }
258+ } else {
259+ lines . push ( `${ pad } Wire.write((uint8_t)(${ value } ));` ) ;
260+ }
261+ lines . push ( `${ pad } Wire.endTransmission();` ) ;
262+ return {
263+ parts : [
264+ lines ,
265+ { portId : 'out' , depthDelta : 0 }
266+ ]
267+ } ;
268+ }
269+ } ,
270+ {
271+ id : 'i2c_mem_read' ,
272+ name : 'I2C Mem Read' ,
273+ color : '#0ea5e9' ,
274+ icon : '📖' ,
275+ category : 'i2c' ,
276+ description : 'อ่านข้อมูลจาก register address ภายใน I2C device (beginTransmission → write reg → endTransmission → requestFrom → read)' ,
277+ inputs : [ { id : 'in' , type : 'input' , label : '➜' , dataType : 'any' , description : 'รับสายลำดับการทำงานจากบล็อกก่อนหน้า' } ] ,
278+ outputs : [ { id : 'value' , type : 'output' , label : 'Value' , dataType : 'int' , description : 'ค่าที่อ่านได้ (byte = 0–255, word = 0–65535)' } ] ,
279+ params : [
280+ { id : 'address' , type : 'number' , label : 'Device Addr (hex)' , default : '0x68' , description : 'I2C address ของ device' } ,
281+ { id : 'reg' , type : 'number' , label : 'Register (hex)' , default : '0x00' , description : 'register address ภายใน device' } ,
282+ {
283+ id : 'size' , type : 'option' , label : 'Size' ,
284+ options : [
285+ { label : 'Byte (1 byte)' , value : 'byte' } ,
286+ { label : 'Word (2 bytes)' , value : 'word' } ,
287+ ] ,
288+ description : 'ขนาดข้อมูลที่จะอ่าน'
289+ } ,
290+ {
291+ id : 'endian' , type : 'option' , label : 'Endian' ,
292+ options : [
293+ { label : 'Big-endian (BE)' , value : 'BE' } ,
294+ { label : 'Little-endian (LE).' , value : 'LE' } ,
295+ ] ,
296+ description : 'ลำดับไบต์ Big-endian / Little-endian'
297+ } ,
298+ ] ,
299+ toCode ( { pad, block, safeId, params, registerPreprocessor } ) {
300+ registerPreprocessor ( '#include <Wire.h>' ) ;
301+ const id = safeId ( block . id ) ;
302+ const addr = params . address ?? '0x68' ;
303+ const reg = params . reg ?? '0x00' ;
304+ const size = params . size ?? 'byte' ;
305+ const endian = params . endian ?? 'BE' ;
306+ const lines : string [ ] = [
307+ `${ pad } Wire.beginTransmission(${ addr } );` ,
308+ `${ pad } Wire.write(${ reg } );` ,
309+ `${ pad } Wire.endTransmission(false);` ,
310+ `${ pad } Wire.requestFrom(${ addr } , (uint8_t)${ size === 'word' ? '2' : '1' } );` ,
311+ ] ;
312+ if ( size === 'word' ) {
313+ lines . push ( `${ pad } int ${ id } = 0;` ) ;
314+ lines . push ( `${ pad } if (Wire.available() >= 2) {` ) ;
315+ lines . push ( `${ pad } uint8_t ${ id } _hi = Wire.read();` ) ;
316+ lines . push ( `${ pad } uint8_t ${ id } _lo = Wire.read();` ) ;
317+ if ( endian === 'BE' ) {
318+ lines . push ( `${ pad } ${ id } = (${ id } _hi << 8) | ${ id } _lo;` ) ;
319+ } else {
320+ lines . push ( `${ pad } ${ id } = (${ id } _lo << 8) | ${ id } _hi;` ) ;
321+ }
322+ lines . push ( `${ pad } }` ) ;
323+ } else {
324+ lines . push ( `${ pad } int ${ id } = Wire.available() ? Wire.read() : 0;` ) ;
325+ }
326+ return {
327+ parts : [
328+ lines ,
329+ { portId : 'value' , depthDelta : 0 }
330+ ]
331+ } ;
332+ }
333+ } ,
169334 ]
170335} ;
0 commit comments