#include <Arduino.h>
bool running = false; // Флаг выполнения
String setupCode = ""; // Код для setup()
String loopCode = ""; // Код для loop()
bool setupExecuted = false; // Убедиться, что setup выполняется только один раз
struct Variable {
String name;
int value;
};
Variable variables[10]; // Статический массив для хранения переменных (максимум 10 переменных)
int variableCount = 0;
// Найти переменную по имени
int findVariableIndex(const String &name) {
for (int i = 0; i < variableCount; i++) {
if (variables[i].name == name) {
return i;
}
}
return -1;
}
// Добавить или обновить переменную
void addOrUpdateVariable(const String &name, int value) {
int index = findVariableIndex(name);
if (index == -1) {
if (variableCount < 10) { // Проверка на лимит переменных
variables[variableCount++] = {name, value};
Serial.print("Variable added: ");
} else {
Serial.println("Error: Maximum number of variables reached.");
return;
}
} else {
variables[index].value = value;
Serial.print("Variable updated: ");
}
Serial.print(name);
Serial.print(" = ");
Serial.println(value);
}
// Выполнить блок кода
void parseAndExecuteBlock(const String &block) {
int startIdx = 0;
int endIdx = 0;
int braceCount = 0;
while (startIdx < block.length()) {
endIdx = startIdx;
while (endIdx < block.length()) {
char c = block[endIdx];
if (c == '{') {
braceCount++;
} else if (c == '}') {
braceCount--;
} else if (c == ';' && braceCount == 0) {
break;
}
endIdx++;
}
String line = block.substring(startIdx, endIdx + 1);
line.trim();
if (line.length() > 0) {
parseAndExecute(line);
}
startIdx = endIdx + 1;
}
}
// Выполнить строку кода
void parseAndExecute(const String &line) {
String trimmedLine = line;
trimmedLine.trim();
if (trimmedLine.length() == 0) {
return; // Пропуск пустых строк
}
Serial.print("Executing line: ");
Serial.println(trimmedLine);
if (trimmedLine.startsWith("pinMode")) {
int pin;
char mode[20];
if (sscanf(trimmedLine.c_str(), "pinMode(%d, %19[^)])", &pin, mode) == 2) {
if (strcmp(mode, "OUTPUT") == 0) pinMode(pin, OUTPUT);
else if (strcmp(mode, "INPUT") == 0) pinMode(pin, INPUT);
else if (strcmp(mode, "INPUT_PULLUP") == 0) pinMode(pin, INPUT_PULLUP);
Serial.print("pinMode set for pin ");
Serial.print(pin);
Serial.print(" as ");
Serial.println(mode);
}
} else if (trimmedLine.startsWith("digitalWrite")) {
int pin;
char state[10];
if (sscanf(trimmedLine.c_str(), "digitalWrite(%d, %9[^)])", &pin, state) == 2) {
int value = strcmp(state, "HIGH") == 0 ? HIGH : LOW;
digitalWrite(pin, value);
Serial.print("Pin ");
Serial.print(pin);
Serial.print(" set to ");
Serial.println(state);
} else {
Serial.println("Error: Invalid digitalWrite syntax.");
}
} else if (trimmedLine.startsWith("delay")) {
String valueStr = trimmedLine.substring(trimmedLine.indexOf('(') + 1, trimmedLine.indexOf(')'));
valueStr.trim();
int duration;
int varIndex = findVariableIndex(valueStr);
if (varIndex != -1) duration = variables[varIndex].value;
else sscanf(valueStr.c_str(), "%d", &duration);
delay(duration);
Serial.print("Delaying for ");
Serial.print(duration);
Serial.println(" ms");
} else if (trimmedLine.startsWith("if")) {
int conditionStart = trimmedLine.indexOf('(') + 1;
int conditionEnd = trimmedLine.lastIndexOf(')');
String condition = trimmedLine.substring(conditionStart, conditionEnd);
if (!condition.startsWith("digitalRead")) {
conditionEnd = trimmedLine.indexOf(')');
}
condition.trim();
Serial.print(") condition ");
Serial.println(condition);
bool result = false;
int eqIndex = condition.indexOf("==");
if (eqIndex != -1) {
String left = condition.substring(0, eqIndex);
String right = condition.substring(eqIndex + 2);
left.trim();
right.trim();
int leftValue = 0;
if (left.startsWith("digitalRead")) {
int pin;
if (sscanf(left.c_str(), "digitalRead(%d)", &pin) == 1) {
leftValue = digitalRead(pin);
Serial.print("digitalRead(");
Serial.print(pin);
Serial.print(") returned ");
Serial.println(leftValue);
}
} else {
leftValue = findVariableIndex(left) != -1 ? variables[findVariableIndex(left)].value : left.toInt();
}
int rightValue = findVariableIndex(right) != -1 ? variables[findVariableIndex(right)].value : right.toInt();
result = (leftValue == rightValue);
Serial.print("Condition result: ");
Serial.print(leftValue);
Serial.print(" :: ");
Serial.print(rightValue);
Serial.println(result ? "true" : "false");
}
int blockStart = trimmedLine.indexOf('{');
int blockEnd = trimmedLine.lastIndexOf('}');
if (blockStart != -1 && blockEnd != -1) {
String block = trimmedLine.substring(blockStart + 1, blockEnd);
if (result) {
Serial.println("Condition is true, executing block");
parseAndExecuteBlock(block);
} else {
Serial.println("Condition is false, skipping block");
}
} else {
Serial.println("Error: Missing or invalid block in if condition");
}
}
else if (trimmedLine.startsWith("int") || trimmedLine.startsWith("float") || trimmedLine.startsWith("String")) {
String declaration = trimmedLine.substring(trimmedLine.indexOf(' ') + 1);
int eqIndex = declaration.indexOf('=');
String name = declaration.substring(0, eqIndex);
name.trim();
int value = declaration.substring(eqIndex + 1).toInt();
addOrUpdateVariable(name, value);
} else {
Serial.print("Unknown command: ");
Serial.println(trimmedLine);
}
}
void setup() {
Serial.begin(115200);
Serial.println("Ready to receive code");
}
void loop() {
static String incomingCode = "";
// Чтение входящих данных
while (Serial.available()) {
char c = Serial.read();
if (c == '\n') {
incomingCode.trim();
Serial.println("Received code: " + incomingCode);
if (incomingCode.startsWith("int") || incomingCode.startsWith("float") || incomingCode.startsWith("String")) {
parseAndExecute(incomingCode); // Обрабатываем переменные сразу
} else if (incomingCode.startsWith("void setup()")) {
setupCode = incomingCode.substring(incomingCode.indexOf('{') + 1, incomingCode.lastIndexOf('}'));
setupCode.trim();
} else if (incomingCode.startsWith("void loop()")) {
loopCode = incomingCode.substring(incomingCode.indexOf('{') + 1, incomingCode.lastIndexOf('}'));
loopCode.trim();
} else if (incomingCode == "RUN") {
running = true;
setupExecuted = false;
} else if (incomingCode == "STOP") {
running = false;
}
incomingCode = "";
} else {
incomingCode += c;
}
}
// Режим выполнения пользовательского кода
if (running) {
// Выполняем setup только один раз
if (!setupExecuted && setupCode.length() > 0) {
Serial.println("Executing setup code...");
parseAndExecuteBlock(setupCode);
setupExecuted = true;
}
// Выполняем loop-код
if (loopCode.length() > 0) {
Serial.println("Executing loop code...");
parseAndExecuteBlock(loopCode);
} else {
Serial.println("No loop code to execute.");
}
} else {
delay(10); // Уменьшаем нагрузку на CPU, если ничего не выполняется
}
}