Skip to content

Commit 1a98f4d

Browse files
committed
Add I2C write bytes, mem write, mem read
1 parent f764dde commit 1a98f4d

1 file changed

Lines changed: 165 additions & 0 deletions

File tree

src/lib/blocks/i2c.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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-9a-fA-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

Comments
 (0)