Skip to content
Open
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
110 changes: 109 additions & 1 deletion ArduinoFrontend/src/app/Libs/outputs/Arduino.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isUndefined, isNull } from 'util';
import { Point } from '../Point';
import { EventEmitter } from '@angular/core';
import { GraphDataService } from 'src/app/graph-data.service';
import { AlertService } from '../../alert/alert-service/alert.service';

/**
* AVR8 global variable
Expand Down Expand Up @@ -46,6 +47,7 @@ export class ArduinoUno extends CircuitElement {
* Pin Names Mapped to the respective Node
*/
public pinNameMap: any = {};
private usedPins: string[] = [];
/**
* Servo attached to an arduino
*/
Expand Down Expand Up @@ -145,6 +147,111 @@ export class ArduinoUno extends CircuitElement {
});
}
}
/**
* what pins of arduino were used
*/
trackUsedPins() {
this.usedPins = []; // Clear previous entries
window['scope'].ArduinoUno.forEach(arduino => {
arduino.nodes.forEach(point => {
if (point.connectedTo) {
// console.log("Before mapping - Point Label:", point.label);
this.usedPins.push(point.label);
}
});
});
console.log('Used Pins In Circuit:', this.usedPins);
}
/**
* extract pins from code
*/
extractUsedPins(code: string): string[] {
// Regex to capture pin assignments like `int led = 13;` or `const int rs = A0;`
const assignmentRegex = /\b(?:const\s+)?(?:int|byte)\s+(\w+)\s*=\s*(A?\d+);/g;
// Regex to capture function calls like `pinMode(13, OUTPUT);`, `digitalWrite(led, HIGH);`
const pinRegex = /\b(?:pinMode|digitalWrite|analogWrite|analogRead|\w+\.attach)\s*\(\s*(\w+)\s*,?/g;
// Regex to capture the LiquidCrystal constructor
const liquidCrystalRegex = /LiquidCrystal\s*\w*\s*\(\s*([\dA-Za-z,\s]+)\s*\)/g;
const pinMap: Record<string, string> = {}; // Store variable assignments
let match;
// Extract and store variable assignments
match = assignmentRegex.exec(code);
while (match !== null) {
pinMap[match[1]] = match[2]; // Store { led: "13" }, { rs: "A0" }
match = assignmentRegex.exec(code);
}
const pins: Set<string> = new Set();
// Extract function call pins and replace variables with their values
match = pinRegex.exec(code);
while (match !== null) {
let pin = match[1]; // Variable or direct number (e.g., "led" or "13")
if (pin === 'LED_BUILTIN') {
pin = '13';
} else if (pinMap[pin]) {
pin = pinMap[pin]; // Replace with assigned pin number
}

if (pin.startsWith('A')) {
// If it's an analog pin (A0 to A5), add it as is.
pins.add(pin);
} else if (!isNaN(Number(pin))) {
// If it's a number, map it as a digital pin "D{pin}"
pins.add(`D${pin}`);
}
match = pinRegex.exec(code);
}
match = liquidCrystalRegex.exec(code);
while (match !== null) {
const pinArgs = match[1].trim(); // Get the arguments inside the LiquidCrystal constructor
// Split the arguments by commas (e.g., "12, 11, 5, 4, 3, 2")
pinArgs.split(',').forEach(pin => {
pin = pin.trim(); // Remove any leading or trailing spaces

// If the pin is a variable, replace it with its assigned value
if (pinMap[pin]) {
pin = pinMap[pin]; // Replace with assigned pin number
}

// Add the pins to the set with proper formatting
if (pin.startsWith('A')) {
// If it's an analog pin, add it as is.
pins.add(pin);
} else if (!isNaN(Number(pin))) {
// If it's a numeric pin, treat it as a digital pin.
pins.add(`D${pin}`);
}
});
match = liquidCrystalRegex.exec(code);
}
const pinsArray: string[] = [];
pins.forEach((pin) => {
pinsArray.push(pin); // Push each value to the array
});
console.log('Extracted Pins From Code:', pinsArray);
return pinsArray;
}
/**
* Method to check if there are any mismatched pins between used and declared pins
*/
checkPinMismatches() {
const usedPinsFromCode = this.extractUsedPins(this.code);
const connectedPins = this.usedPins.filter(pin => pin !== 'GND' && pin !== '5V' && pin !== '3.3V'); // Exclude GND, 5V, and 3.3V

const codeMismatchedPins = usedPinsFromCode.filter(pin => !connectedPins.includes(pin));
const cricuitMismatchedPins = connectedPins.filter(pin => !usedPinsFromCode.includes(pin));
if (codeMismatchedPins.length > 0) {
// console.error('The following pins are declared in the code but not connected in the simulation:', mismatchedPins);
const errorMessage = `The following pins are declared in the code but NOT CONNECTED in the CIRCUIT: ${codeMismatchedPins.join(', ')}`;
AlertService.showAlert(errorMessage);
} else if (cricuitMismatchedPins.length > 0) {
// console.error('The following pins are connected in the circuit but not declared in the code:', cricuitMismatchedPins);
const errMessage = `The following pins are connected in the circuit but NOT DECLARED in the CODE: ` +
`${cricuitMismatchedPins.join(', ')}`;
AlertService.showAlert(errMessage);
} else {
console.log('All pins in the code are correctly connected.');
}
}
/**
* Data which needs to be saved inside the database
*/
Expand Down Expand Up @@ -342,7 +449,8 @@ export class ArduinoUno extends CircuitElement {
this.runner.portD.setPin(i, 1);
}
}

this.trackUsedPins();
this.checkPinMismatches();
}
/**
* Remove arduino runner on stop simulation.
Expand Down