Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions arduino/arduino.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
#define OP_PULSE 17
#define OP_TOGGLE 18
#define OP_ANALOG_RANGE 19
#define OP_ANALOG_COMPARE_GT 20
#define OP_ANALOG_COMPARE_GE 21
#define OP_ANALOG_COMPARE_LT 22
#define OP_ANALOG_COMPARE_LE 23
#define OP_ANALOG_COMPARE_EQ 24
#define OP_ANALOG_COMPARE_NE 25
#define OP_SHIFT_REGISTER 26

const int MAX_INSTRUCTIONS = 300;
const int MAX_VARIABLES = 60;
Expand Down Expand Up @@ -399,6 +406,100 @@ void executeInstructions() {
variables[outputVar] = (value >= min && value <= max) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_GT: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
variables[outputVar] = (variables[aVar] > variables[bVar]) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_GE: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
variables[outputVar] = (variables[aVar] >= variables[bVar]) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_LT: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
variables[outputVar] = (variables[aVar] < variables[bVar]) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_LE: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
variables[outputVar] = (variables[aVar] <= variables[bVar]) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_EQ: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
// Add a small tolerance for analog value comparisons
variables[outputVar] = (abs(variables[aVar] - variables[bVar]) < 5) ? 1 : 0;
break;
}
case OP_ANALOG_COMPARE_NE: {
byte aVar = instructions[pc++];
byte bVar = instructions[pc++];
byte outputVar = instructions[pc++];
// Add a small tolerance for analog value comparisons
variables[outputVar] = (abs(variables[aVar] - variables[bVar]) >= 5) ? 1 : 0;
break;
}
case OP_SHIFT_REGISTER: {
byte dataVar = instructions[pc++];
byte clockVar = instructions[pc++];
byte resetVar = instructions[pc++];
byte numOutputs = instructions[pc++];
byte initialState = instructions[pc++];
byte baseOutputVar = instructions[pc++];

static bool shiftRegisterInitialized[MAX_VARIABLES] = {false};
static uint8_t shiftRegisterState[MAX_VARIABLES] = {0};
static bool prevClockState[MAX_VARIABLES] = {false};

// Initialize on first run
if (!shiftRegisterInitialized[baseOutputVar]) {
// Set only the initial output bit high, others low
shiftRegisterState[baseOutputVar] = (1 << initialState);
shiftRegisterInitialized[baseOutputVar] = true;
}

// Reset logic - only if reset is connected (not 255) and reset is HIGH
if (resetVar != 255 && variables[resetVar] == HIGH) {
// Reset to initial state (only the initial output bit high)
shiftRegisterState[baseOutputVar] = (1 << initialState);
}

// Clock rising edge detection
bool currentClockState = variables[clockVar];
if (currentClockState && !prevClockState[baseOutputVar]) {
// On rising edge of clock, shift the register
if (variables[dataVar]) {
// Shift left and set LSB to 1
shiftRegisterState[baseOutputVar] = (shiftRegisterState[baseOutputVar] << 1) | 0x01;
} else {
// Shift left and set LSB to 0
shiftRegisterState[baseOutputVar] = (shiftRegisterState[baseOutputVar] << 1) & 0xFE;
}

// Handle wrap-around for the number of outputs
if (shiftRegisterState[baseOutputVar] >= (1 << numOutputs)) {
shiftRegisterState[baseOutputVar] = 1; // Reset to first output
}
}
prevClockState[baseOutputVar] = currentClockState;

// Set output variables (one for each output)
for (byte i = 0; i < numOutputs; i++) {
variables[baseOutputVar + i] = (shiftRegisterState[baseOutputVar] >> i) & 0x01;
}
break;
}

}
}
Expand Down
111 changes: 111 additions & 0 deletions logic-editor/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -727,3 +727,114 @@ test('larger project without OR. connecting two buttons to same input', () => {

expect(bytecodeToString(generateBytecode(test as any))).toEqual(expectedBytecode);
});

test('analogComparerNode test', () => {
const test = {
"nodes": [
{
"id": "dndnode_0",
"type": "analogComparerNode",
"position": {
"x": 355.08583015996766,
"y": 267.65848888782415
},
"data": {
"label": "analogComparerNode",
"inputs": 2,
"selectedBoard": "arduino_nano"
},
"width": 160,
"height": 103
},
{
"id": "dndnode_1",
"type": "inputNode",
"position": {
"x": 177.975220378801,
"y": 253.12988417921287
},
"data": {
"label": "inputNode",
"inputs": 2,
"selectedBoard": "arduino_nano",
"pin": "14"
},
"width": 97,
"height": 59,
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 177.975220378801,
"y": 253.12988417921287
}
},
{
"id": "dndnode_2",
"type": "inputNode",
"position": {
"x": 173.82419046205496,
"y": 319.5463628471503
},
"data": {
"label": "inputNode",
"inputs": 2,
"selectedBoard": "arduino_nano",
"pin": "15"
},
"width": 97,
"height": 59,
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 173.82419046205496,
"y": 319.5463628471503
}
},
{
"id": "dndnode_3",
"type": "outputNode",
"position": {
"x": 569.5557091918491,
"y": 304.3259198190813
},
"data": {
"label": "outputNode",
"inputs": 2,
"selectedBoard": "arduino_nano",
"pin": "13"
},
"width": 97,
"height": 59,
"selected": false,
"dragging": false
}
],
"edges": [
{
"source": "dndnode_1",
"sourceHandle": "out",
"target": "dndnode_0",
"targetHandle": "a",
"id": "reactflow__edge-dndnode_1out-dndnode_0a"
},
{
"source": "dndnode_2",
"sourceHandle": "out",
"target": "dndnode_0",
"targetHandle": "b",
"id": "reactflow__edge-dndnode_2out-dndnode_0b"
},
{
"source": "dndnode_0",
"sourceHandle": "out",
"target": "dndnode_3",
"targetHandle": "in",
"id": "reactflow__edge-dndnode_0out-dndnode_3in"
}
],
"board": "arduino_nano"
};
const expectedBytecode = "1,14,1,15,2,13,5,14,0,5,15,1,20,0,1,2,4,13,2";

expect(bytecodeToString(generateBytecode(test as any))).toEqual(expectedBytecode);
});
Loading