A visual programming environment for Arduino and ESP32 development. This tool allows you to create Arduino programs by connecting visual nodes in a flow-based interface, without writing code manually.
- Drag-and-drop interface for creating Arduino programs
- Visual node-based programming
- Automatic Arduino code generation
- Support for various sensors and output devices
- Logic nodes for conditional operations
- Real-time code preview
# Clone the repository
git clone https://github.com/yourusername/visual-automations.git
cd visual-automations
# Install dependencies
npm install
# Start the development server
npm run dev
- Drag components from the left panel onto the canvas
- Connect nodes by clicking and dragging from one handle to another
- Configure each node's parameters
- Click "Generate Arduino Code" to see the resulting code
- Copy the generated code to the Arduino IDE or use it directly with your preferred upload method
The project is built with React and uses the following key libraries:
- ReactFlow: Provides the core flow-based canvas functionality
- Zustand: State management for the application
- Vite: Build tool and development server
Flow.jsx
: Main component that renders the ReactFlow canvas and handles node interactionsNodePanel.jsx
: Side panel that displays available nodes for dragging onto the canvasnodes/
: Directory containing all node type implementations:ArduinoNode.jsx
: Configuration node for Arduino settingsSensorNode.jsx
: Input nodes for various sensorsOutputNode.jsx
: Output nodes for LEDs, relays, etc.LogicNode.jsx
: Conditional logic nodes
store.js
: Zustand store that manages application state and code generationCodePreview.jsx
: Component for displaying generated Arduino code
Contributions are welcome! Here's how you can help improve Visual Automations:
One of the most valuable contributions is adding new node types to support additional Arduino components and functionality.
Create a new file in the src/components/nodes/
directory. Use the existing node components as templates.
// src/components/nodes/MyNewNode.jsx
import React, { useState } from 'react';
import { Handle, Position } from 'reactflow';
function MyNewNode({ data }) {
const [params, setParams] = useState(data.params || {
// Default parameters for your node
myParam1: 'default',
myParam2: 'value'
});
// Update node data when parameters change
const handleParamChange = (e) => {
const { name, value } = e.target;
const updatedParams = {
...params,
[name]: value
};
setParams(updatedParams);
data.params = updatedParams;
};
return (
<div className="node my-new-node-type">
<div className="node-header">{data.label}</div>
<div className="node-content">
{/* Add your node's UI controls here */}
<div className="node-param">
<label>My Parameter:</label>
<input
type="text"
name="myParam1"
value={params.myParam1 || 'default'}
onChange={handleParamChange}
/>
</div>
</div>
{/* Add handles as needed */}
<Handle type="target" position={Position.Top} id="in" />
<Handle type="source" position={Position.Bottom} id="out" />
</div>
);
}
export default MyNewNode;
Add your new node type to the nodeTypes
object in Flow.jsx
:
// In Flow.jsx
import MyNewNode from './nodes/MyNewNode';
// Define custom node types
const nodeTypes = {
arduinoNode: ArduinoNode,
sensorNode: SensorNode,
outputNode: OutputNode,
logicNode: LogicNode,
myNewNode: MyNewNode, // Add your new node type here
};
Add your node to the NodePanel.jsx
component so users can drag it onto the canvas:
// In NodePanel.jsx
<div className="node-item my-new-type"
onDragStart={(e) => onDragStart(e, 'myNewNode', 'My New Node')}
draggable>
My New Node
</div>
Modify the generateArduinoCode
function in store.js
to handle your new node type:
// In store.js, within the generateArduinoCode function
// Find your new nodes
const myNewNodes = nodes.filter(node => node.type === 'myNewNode');
// Add any necessary includes or pin definitions
myNewNodes.forEach(node => {
// Add code generation logic for your node type
});
// Add setup code if needed
myNewNodes.forEach(node => {
// Add setup code for your node type
});
// Add loop code if needed
myNewNodes.forEach(node => {
// Add loop code for your node type
});
- Consistent UI: Follow the existing UI patterns for node appearance and behavior
- Descriptive Parameters: Use clear labels and appropriate input types for parameters
- Default Values: Always provide sensible default values for parameters
- Code Generation: Ensure your node generates clean, efficient Arduino code
- Error Handling: Validate inputs and handle edge cases gracefully
- Bug fixes: Help identify and fix bugs in the existing codebase
- Documentation: Improve this README or add additional documentation
- UI Improvements: Enhance the user interface and experience
- Testing: Add tests for components and functionality
MIT