Skip to content

Commit 2e185df

Browse files
clean up and adding more env vars, adding more info to README
1 parent 46a3534 commit 2e185df

File tree

5 files changed

+154
-33
lines changed

5 files changed

+154
-33
lines changed

.env.dist

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
API_HOST=http://localhost:8000
1+
# API Config
2+
API_HOST=http://localhost:3000
3+
4+
# Arduino Config
5+
SERIALPORT=/dev/tty.SLAB_USBtoUART
6+
BAUDRATE=9600
7+
INTERVAL=500

README.md

Lines changed: 126 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,157 @@
11
# arduino-serial-fetch
22

3-
## Simple NodeJS app that converts serial messages to REST API requests
3+
This app converts serial messages from an Arduino to REST API requests. It has been developed to correspond specifically with the REST API service provided by [arduino-api-server](https://github.com/stephiescastle/arduino-api-server) and is structured solely to update pin data.
44

5-
This api will allow your arduino to send and receive data to a remote server. This means you can retrieve data from other arduinos and alternatively make your data available to others. Additionally, the endpoints for your arduino can be used as a data endpoint in other apps, i.e. p5.js, Max/MSP, etc.
5+
- [Requirements](#requirements)
6+
- [Getting Started](#getting-started)
7+
- [Arduino code and `Serial.print()` format](#arduino-code-and-serialprint-format)
8+
- [Adding more pins](#adding-more-pins)
9+
- [Test API endpoints](#test-api-endpoints)
610

7-
This is achievable by using two repos:
8-
9-
1. [arduino-serial-fetch](https://github.com/stephiescastle/arduino-serial-fetch) - (aka this repo) - The node.js app that reads from and writes to your arduino board. The node.js app runs locally alongside your arduino board.
10-
2. [arduino-api-server](https://github.com/stephiescastle/arduino-api-server) - The server that provides the data endpoints and is deployed to heroku.
11-
12-
This was developed to help facilitate the creation of interactive, physical computing-based works while we all live in quarantine.
13-
14-
## Dependencies
11+
## Requirements
1512

1613
- [arduino-api-server](https://github.com/stephiescastle/arduino-api-server)
17-
- node.js
18-
- arduino program must be printing data to the serial port with a delimiter (see [/arduinoSerial/arduinoSerial.ino](/arduinoSerial/arduinoSerial.ino))
19-
- arduino must be tethered via USB
14+
- Arduino serial messages must following a specific format. See [Arduino code and `Serial.print()` format](#arduino-code-and-serialprint-format)
15+
- Arduino must be tethered to your computer
2016

21-
### Getting Started
17+
## Getting Started
2218

23-
1. Set up your [arduino-api-server](https://github.com/stephiescastle/arduino-api-server)
24-
2. Create your env file.
19+
1. First complete your [arduino-api-server](https://github.com/stephiescastle/arduino-api-server) setup
20+
2. Connect your Arduino to your computer and upload the corresponding Arduino program to it. See [Arduino code and `Serial.print()` format](#arduino-code-and-serialprint-format).
21+
3. Create your env file.
2522

2623
```bash
2724
cp .env.dist .env
2825
```
2926

30-
3. Update the `.env` file with your `API_HOST`. This corresponds to the URL of your API server.
27+
4. Update the `.env` file with values that match your configuration:
3128

32-
4. Connect your arduino to your computer and upload the corresponding arduino program to it (you may need to modify this for the pins you are actually using)
29+
| var | default | description |
30+
| :----------- | :------------------------ | :--------------------------------------------------------------------------------------------------------------- |
31+
| `API_HOST` | `http://localhost:3000` | The host URL of your API server (see [arduino-api-server](https://github.com/stephiescastle/arduino-api-server)) |
32+
| `SERIALPORT` | `/dev/tty.SLAB_USBtoUART` | The serial port your Arduino is connected to. Should match the port name you use in the Arduino IDE. |
33+
| `BAUDRATE` | `9600` | Match the baudrate used in your Arduino code. Check `Serial.begin(9600);` in your Arduino `setup()` |
34+
| `INTERVAL` | `500` | Frequency of API requests (in milliseconds) |
3335

3436
5. Install dependencies
3537

3638
```bash
3739
npm install
3840
```
3941

40-
6. Run arduino-serial-fetch
42+
6. Run the app
4143

4244
```bash
4345
npm start
4446
```
4547

46-
### Test changing a value
48+
To stop the app, use ctrl-c (`^C`)
49+
50+
## Arduino code and `Serial.print()` format
51+
52+
This app assumes that your Arduino code is only printing one line to the Serial port per `loop()` iteration and is constructed like so:
53+
54+
```js
55+
// for three pins
56+
<number>\t<number>\t<number>\t\n
57+
```
58+
59+
Each number represents pin data, with `\t` as the delimiter. `\n` signifies the end of the data reading for one iteration in `loop()`. It is up to the interpreter to know the order of the pins and how that should correspond to their usage (see [Adding more pins](#adding-more-pins)).
60+
61+
You can use [/arduinoSerial/arduinoSerial.ino](/arduinoSerial/arduinoSerial.ino) as boilerplate for your Arduino code with pins modified as needed.
62+
63+
## Adding more pins
64+
65+
The app defaults to reading and sending the following pins:
66+
67+
- `A0`
68+
- `A1`
69+
- `D2`
70+
71+
This can be modified by updating both the:
72+
73+
1. Arduino code: read the necessary pins and append to the `Serial.print` message
74+
2. `main.js`: modify the constructed `allPins` array that is used to generate API requests.
75+
76+
For example, say I needed to read pins `A0`, `A3`, `D4`, and `D7`. I would need to modify my code like so:
77+
78+
```c++
79+
// arduinoSerial.ino
80+
81+
int knobPin = A0;
82+
int knobValue = 0;
4783

48-
If you don't have your arduino connected, you can manually update pin values via the `test.js` script. This is useful if you just want to test your endpoints.
84+
int sensorPin = A3;
85+
int sensorValue = 0;
86+
87+
int button1Pin = D4;
88+
int button1Value = 0;
89+
90+
int button2Pin = D7;
91+
int button2Value = 0;
92+
93+
void setup() {
94+
pinMode(button1Pin, INPUT);
95+
pinMode(button2Pin, INPUT);
96+
Serial.begin(9600);
97+
}
98+
99+
void loop() {
100+
// A0 will be pins[0]
101+
knobValue = analogRead(knobPin);
102+
Serial.print(knobValue);
103+
Serial.print("\t");
104+
105+
// A3 will be pins[1]
106+
sensorValue = analogRead(sensorPin);
107+
Serial.print(sensorValue);
108+
Serial.print("\t");
109+
110+
// D4 will be pins[2]
111+
buttonValue = digitalRead(button1Pin);
112+
Serial.print(button1Value);
113+
Serial.print("\t");
114+
115+
// D7 will be pins[3]
116+
buttonValue = digitalRead(button2Pin);
117+
Serial.print(button2Value);
118+
Serial.print("\t");
119+
120+
Serial.println();
121+
122+
}
123+
```
124+
125+
```js
126+
// main.js excerpt
127+
const allPins = [
128+
{
129+
id: "A0",
130+
value: pins[0],
131+
},
132+
{
133+
id: "A3",
134+
value: pins[1],
135+
},
136+
{
137+
id: "D4",
138+
value: pins[2],
139+
},
140+
{
141+
id: "D7",
142+
value: pins[3],
143+
},
144+
];
145+
```
146+
147+
> Note how the `pins[]` array index does not necessarily correspond to the Arduino pin number.
148+
149+
## Test API endpoints
150+
151+
If you don't have an Arduino connected, you can mimic one with the `test.js` script. This is useful if you just want to test your endpoints. The test script will also send API requests at the same `INTERVAL` defined in your `.env` file.
49152

50153
```bash
51154
npm test
52155
```
156+
157+
To stop the test, use ctrl-c (`^C`)

arduinoSerial/arduinoSerial.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Basis for arduino code
22
** Each pin should be read and printed on the same line
3-
** index.js pins array usage should correspond with the order you are sending your pins here
3+
** main.js construction of allPins from pins[] should correspond with the order of the pins in this arduino code
44
*/
55

66
int knobPin = A0;
@@ -24,19 +24,19 @@ void loop() {
2424
// read each pint and print everything on a single line separated by \t and ending with \n
2525

2626
// A0
27-
// will be pins[0]
27+
// will be pins[0] in main.js
2828
knobValue = analogRead(knobPin);
2929
Serial.print(knobValue);
3030
Serial.print("\t");
3131

3232
// A1
33-
// will be pins[1]
33+
// will be pins[1] in main.js
3434
sensorValue = analogRead(sensorPin);
3535
Serial.print(sensorValue);
3636
Serial.print("\t");
3737

3838
// D2
39-
// will be pins[2]
39+
// will be pins[2] in main.js
4040
buttonValue = digitalRead(buttonPin);
4141
Serial.print(buttonValue);
4242
Serial.print("\t");

main.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ const fetch = require("node-fetch");
44
const SerialPort = require("serialport");
55
const Readline = require("@serialport/parser-readline");
66

7-
// vars *️⃣ update to match your configuration
8-
const portName = process.env.SERIALPORT || "/dev/cu.SLAB_USBtoUART"; // the name of the serial port (same as arduino port)
9-
const baudRate = process.env.BAUDRATE || 9600; // should match the arduino's baudrate
10-
const interval = process.env.INTERVAL || 500; // time interval for POST requests
7+
// vars populated by .env file
8+
const portName = process.env.SERIALPORT; // the name of the serial port (same as arduino port)
9+
const baudRate = +process.env.BAUDRATE; // should match the arduino's baudrate
10+
const interval = +process.env.INTERVAL; // time interval for API requests
1111

1212
// an empty array to store pin data
1313
let pins = [];
@@ -39,7 +39,7 @@ port.on("open", () => {
3939
pins = data.split("\t").map(Number);
4040
});
4141

42-
// send our data to the net
42+
// convert data to API requests at regular intervals
4343
sendData = setInterval(function () {
4444
// create a new array based on parsed data
4545
// *️⃣ add more pins to this array as needed. this should correspond with your arduino code

test.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1-
// manually update pins to test endpoint
1+
/* Test script
2+
** - Does not required a tethered Arduino
3+
** - Generates a random number for each endpoint for each request
4+
** - Only tests three endpoints: A0, A1, D2
5+
*/
6+
7+
// import dependencies
28
require("dotenv").config();
39
const fetch = require("node-fetch");
410

5-
const interval = process.env.INTERVAL || 500; // time interval for POST requests
11+
// get interval
12+
const interval = +process.env.INTERVAL; // time interval for API requests
613

14+
// random number generator
715
function getRandomNumber() {
816
const min = Math.ceil(0);
917
const max = Math.floor(255);
1018
return Math.floor(Math.random() * (max - min) + min);
1119
}
20+
21+
// convert data to API requests at regular intervals
1222
var sendData = setInterval(function () {
1323
const allPins = [
1424
{

0 commit comments

Comments
 (0)