Refact json response and fixed piezo tone
This commit is contained in:
parent
76e9ae14e5
commit
e064e198a3
105
README.md
105
README.md
@ -2,6 +2,10 @@
|
||||
|
||||
A **SIMPLE** REST API based serial communication. Assisted Firmata protocol and johnny-five API, enabling software communication with the Arduino board using the Server API. that's it. Idk about electronics and networking actually. But that piece of knowledge motivated me to make some IoT stuff. Enjoy (づ ̄ ³ ̄)づ
|
||||
|
||||

|
||||
|
||||
<small>*the animation is from ENA BBQ series by JoelG</small>
|
||||
|
||||
## Setup
|
||||
Tools that are required
|
||||
- Arduino Board
|
||||
@ -9,7 +13,7 @@ Tools that are required
|
||||
- [Node.js](https://nodejs.org/en) v16.0.0^ or other javascript runtime
|
||||
|
||||
### Board
|
||||
Arduino assembly guide also available in [johnny-five](https://github.com/rwaldron/johnny-five?tab=readme-ov-file#setup-and-assemble-arduino) documentation\
|
||||
Arduino assembly guide also available in [johnny-five](https://github.com/rwaldron/johnny-five?tab=readme-ov-file#setup-and-assemble-arduino) documentation
|
||||
1. Plug in your Board via USB
|
||||
2. Open Arduino IDE then select your Board
|
||||
3. Go to `File > Examples > Firmata` Select `StandarFirmataPlus`
|
||||
@ -61,8 +65,11 @@ Arduino assembly guide also available in [johnny-five](https://github.com/rwaldr
|
||||
- [Read pin mode](#read-pin-mode)
|
||||
- [Set pin mode](#set-pin-mode)
|
||||
- [LED](#led)
|
||||
- [Read led state](#read-led-state)
|
||||
- [Set led state](#set-led-state)
|
||||
- [Read LED state](#read-led-state)
|
||||
- [Set LED state](#set-led-state)
|
||||
- [RGB LED](#rgb-led)
|
||||
- [Read RGB state](#read-rgb-state)
|
||||
- [Set RGB state](#set-rgb-state)
|
||||
|
||||
## Common HTTP Responses
|
||||
Some HTTP responses are sent with JSON, otherwise an HTML body will be sent which is the default express.js response
|
||||
@ -82,7 +89,7 @@ Some HTTP responses are sent with JSON, otherwise an HTML body will be sent whic
|
||||
"pin_state": {
|
||||
"13": "HIGH"
|
||||
},
|
||||
"message": "Pin 13 Set to HIGH"
|
||||
"message": "Changed pin state 13 to HIGH"
|
||||
}
|
||||
```
|
||||
| Property | Description |
|
||||
@ -98,7 +105,7 @@ This is an example of javascript code sending a request to turn on the LED light
|
||||
async function turnOnLed() {
|
||||
const res = await fetch("http://localhost:3000/led/13/on"); // Set LED to HIGH
|
||||
const data = await res.json();
|
||||
console.log(data);
|
||||
console.log(data); // { status: 200, pin_state: { 13: high }, message: "Pin 13 Set to HIGH" }
|
||||
}
|
||||
```
|
||||
|
||||
@ -168,7 +175,7 @@ async function turnOnLed() {
|
||||
|
||||
## LED
|
||||
|
||||
### Read led state
|
||||
### Read LED state
|
||||
- **URL Endpoint**
|
||||
|
||||
/led/:p/
|
||||
@ -195,17 +202,17 @@ async function turnOnLed() {
|
||||
}
|
||||
```
|
||||
|
||||
### Set led state
|
||||
### Set LED state
|
||||
- **URL Endpoint**
|
||||
|
||||
/pin/:p/:a
|
||||
/led/:p/:a
|
||||
|
||||
- **URL Params**
|
||||
|
||||
| Params | Mark | Type | Required | Description |
|
||||
|--------|------|------|----------|-------------|
|
||||
| p | pin | `string` | true | Seleced pin |
|
||||
| a | act | `'on'`, `'off'` | true | Action |
|
||||
| a | act | `'on'`, `'off'`, `'high'`, `'low'` | true | Action |
|
||||
|
||||
- **Method(s)**
|
||||
|
||||
@ -219,7 +226,85 @@ async function turnOnLed() {
|
||||
"pin_state": {
|
||||
"13": "HIGH"
|
||||
},
|
||||
"message": "Led pin 13 setted HIGH"
|
||||
"message": "Changed pin state 13 to HIGH"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## RGB LED
|
||||
|
||||
### Read RGB state
|
||||
- **URL Endpoint**
|
||||
|
||||
/rgb-led
|
||||
|
||||
- **Body**
|
||||
|
||||
```javascript
|
||||
{
|
||||
r: number,
|
||||
g: number,
|
||||
b: number
|
||||
}
|
||||
```
|
||||
|
||||
- **Method**
|
||||
|
||||
`POST`
|
||||
|
||||
- **Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"pin_state": {
|
||||
"7": true,
|
||||
"6": true,
|
||||
"5": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Set RGB state
|
||||
- **URL Endpoint**
|
||||
|
||||
/rgb-led
|
||||
|
||||
- **Body**
|
||||
|
||||
```javascript
|
||||
{
|
||||
r: {
|
||||
pin: number,
|
||||
value: boolean
|
||||
},
|
||||
g: {
|
||||
pin: number,
|
||||
value: boolean
|
||||
},
|
||||
b: {
|
||||
pin: number,
|
||||
value: boolean
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **Method(s)**
|
||||
|
||||
`PATCH`
|
||||
|
||||
- **Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"pin_state": {
|
||||
"7": true,
|
||||
"6": true,
|
||||
"5": false
|
||||
},
|
||||
"message": "Success changed pins 7, 6, 5 to state HIGH, HIGH, LOW"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -9,13 +9,14 @@ export function readLed (req: Request, res: Response): Response<string | any> {
|
||||
const { p } = req.params;
|
||||
const pin: number = Number.parseInt(p);
|
||||
|
||||
const pinState: digitalValue = board.pins[pin].value == 1 ? 'ON' : 'OFF';
|
||||
const pinState: voltage = board.pins[pin].value == 1 ? 'HIGH' : 'LOW';
|
||||
|
||||
return res.status(200).json({
|
||||
status: 200,
|
||||
pin_state: {
|
||||
[pin]: pinState
|
||||
}
|
||||
},
|
||||
message: `Led pin ${pin} is ${pinState}`
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
@ -32,20 +33,18 @@ export function writeLed (req: Request, res: Response): Response<string | any> {
|
||||
const act: string = a.toLocaleLowerCase();
|
||||
const pin: number = Number.parseInt(p);
|
||||
|
||||
let state: digitalValue;
|
||||
let state: voltage;
|
||||
let volt: voltage;
|
||||
|
||||
try {
|
||||
switch (act) {
|
||||
case 'on':
|
||||
state = 'ON';
|
||||
case 'on' || 'high':
|
||||
state = 'HIGH';
|
||||
volt = 1;
|
||||
console.log(`${req.hostname} | ${pin} | LED: ${state}`);
|
||||
break;
|
||||
case 'off':
|
||||
state = 'OFF';
|
||||
case 'off' || 'low':
|
||||
state = 'LOW';
|
||||
volt = 0;
|
||||
console.log(`${req.hostname} | ${pin} | LED: ${state}`);
|
||||
break;
|
||||
default:
|
||||
console.log(`${req.hostname} | ${pin} | LED: INVALID ACT`);
|
||||
@ -57,9 +56,14 @@ export function writeLed (req: Request, res: Response): Response<string | any> {
|
||||
|
||||
board.digitalWrite(pin, volt);
|
||||
|
||||
console.log(`${req.hostname} | ${pin} | LED: ${state}`);
|
||||
|
||||
res.status(200).json({
|
||||
status: 200,
|
||||
message: `Success changed pin ${pin} to state ${state}`
|
||||
pin_state: {
|
||||
[pin]: state
|
||||
},
|
||||
message: `Changed pin state ${pin} to ${state}`
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
@ -147,19 +151,26 @@ export function writeRgbLed (req: Request, res: Response): Response<string | any
|
||||
isAnode: true
|
||||
})
|
||||
|
||||
const isHigh: boolean | string = true || 'HIGH' || 'high';
|
||||
|
||||
led.red = new Led(r.pin);
|
||||
led.green = new Led(g.pin);
|
||||
led.blue = new Led(b.pin);
|
||||
|
||||
if (r.value == true) led.red.on(); else led.red.off();
|
||||
if (g.value == true) led.green.on(); else led.green.off();
|
||||
if (b.value == true) led.blue.on(); else led.blue.off();
|
||||
if (r.value == isHigh) led.red.on(); else led.red.off();
|
||||
if (g.value == isHigh) led.green.on(); else led.green.off();
|
||||
if (b.value == isHigh) led.blue.on(); else led.blue.off();
|
||||
|
||||
const pins: string = rgbLeds.map(c => c.pin.toString()).join(", ");
|
||||
const values: string = rgbLeds.map(c => `${c.value}`).join(", ");
|
||||
|
||||
return res.status(200).json({
|
||||
status: 200,
|
||||
pin_state: {
|
||||
[r.pin]: led.red.isOn,
|
||||
[g.pin]: led.green.isOn,
|
||||
[b.pin]: led.blue.isOn
|
||||
},
|
||||
message: `Success changed pins ${pins} to state ${values}`
|
||||
});
|
||||
}
|
||||
|
@ -3,7 +3,32 @@ import { Piezo } from "johnny-five";
|
||||
import { Pitch } from "../melodies";
|
||||
|
||||
export function piezoTone (req: Request, res: Response): Response {
|
||||
const pin: number = Number.parseInt(req.params.p);
|
||||
const frequency: number = Number.parseInt(req.params.f);
|
||||
|
||||
const piezo: Piezo = new Piezo(pin);
|
||||
|
||||
piezo.tone(frequency * 7.3, 100);
|
||||
|
||||
return res.status(200).json({
|
||||
status: 200,
|
||||
pin_tone: {
|
||||
[pin]: frequency
|
||||
},
|
||||
message: `Piezo ${pin} tone ${frequency}`
|
||||
});
|
||||
}
|
||||
|
||||
export function piezoNote (req: Request, res: Response): Response {
|
||||
const { pin, note }: { pin: number, note: string } = req.body;
|
||||
const notePitch = Pitch[note.toUpperCase()];
|
||||
|
||||
if (notePitch == null) {
|
||||
return res.status(400).json({
|
||||
status: 400,
|
||||
message: `Invalid note ${note}`
|
||||
});
|
||||
}
|
||||
|
||||
const piezo: Piezo = new Piezo(pin);
|
||||
|
||||
@ -15,7 +40,13 @@ export function piezoTone (req: Request, res: Response): Response {
|
||||
|
||||
return res.status(200).json({
|
||||
status: 200,
|
||||
message: `Piezo ${pin} tone ${note}`
|
||||
pin_tone: {
|
||||
[pin]: notePitch
|
||||
},
|
||||
pin_note: {
|
||||
[pin]: note.toUpperCase()
|
||||
},
|
||||
message: `Piezo ${pin} tone note ${note}`
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,12 +76,17 @@ export function piezoPlayNotes (req: Request, res: Response): Response {
|
||||
})
|
||||
.filter((note) => note[0].trim() != "-");
|
||||
|
||||
const notesS: string = notes.join(", ");
|
||||
const notesS: string = notes.length > 4 ?
|
||||
notes.slice(0, 4).join(", ")+"..." :
|
||||
notes.join(", ");
|
||||
|
||||
piezo.play({ song, tempo });
|
||||
|
||||
return res.status(200).json({
|
||||
status: 200,
|
||||
pin_notes: {
|
||||
[pin]: notes
|
||||
},
|
||||
message: `Piezo ${pin} play notes ${notesS}`
|
||||
});
|
||||
}
|
@ -18,17 +18,22 @@ const io: Server = new Server(server, {
|
||||
}
|
||||
}); // I have no experience at WebSocket, so.. forgive me :)
|
||||
|
||||
// Server configuration
|
||||
const host: string = 'localhost';
|
||||
const port: number = 3000;
|
||||
|
||||
// Express middleware
|
||||
app.use(express.json());
|
||||
app.use(express.static('client'));
|
||||
|
||||
// Socket.io event handlers
|
||||
io.on('connection', socketHandler);
|
||||
|
||||
// HTTP Routes
|
||||
app.use('/', view);
|
||||
app.use('/api-arduino', isBoardConnected, api);
|
||||
app.use('/api-arduino', isBoardConnected, api); // Board API Controllers
|
||||
|
||||
// Run server
|
||||
console.log("\nRunning Server...");
|
||||
server.listen(port, () => {
|
||||
console.log(`Server is connected and running in ${host} at port ${port} 🗣️🗣️🗣️`);
|
||||
|
@ -3,7 +3,7 @@ import { Router } from "express";
|
||||
|
||||
import { readLed, readRgbLed, writeLed, writeRgbLed } from "../controller/led";
|
||||
import { readPin, setPin } from "../controller/pin";
|
||||
import { piezoNoTone, piezoPlayNotes, piezoTone } from "../controller/piezo";
|
||||
import { piezoNoTone, piezoNote, piezoPlayNotes, piezoTone } from "../controller/piezo";
|
||||
import { rotateServo } from "../controller/servo";
|
||||
import { readResistor } from "../controller/photoresistor";
|
||||
|
||||
@ -11,22 +11,28 @@ import { isPinNumeric } from "../middleware/pin";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
// Client page
|
||||
router.get('/hello', (req, res: Response): Response<string> => {
|
||||
return res.status(200).send("Hello");
|
||||
})
|
||||
|
||||
// PinMode
|
||||
router.get('/pin/:p', readPin);
|
||||
router.patch('/pin/:p/:m', setPin);
|
||||
|
||||
// LED
|
||||
router.get('/led/:p', isPinNumeric, readLed);
|
||||
router.patch('/led/:p/:a', isPinNumeric, writeLed);
|
||||
|
||||
router.get('/rgb-led', readRgbLed);
|
||||
// RGB LED
|
||||
router.post('/rgb-led', readRgbLed);
|
||||
router.patch('/rgb-led/', writeRgbLed);
|
||||
|
||||
router.patch('/piezo/', piezoTone);
|
||||
router.patch('/piezo/stop/', piezoNoTone);
|
||||
// Piezo
|
||||
router.patch('/piezo/:p/:f', isPinNumeric, piezoTone);
|
||||
router.patch('/piezo/note', piezoNote);
|
||||
router.patch('/piezo/music/', piezoPlayNotes);
|
||||
router.patch('/piezo/stop/', piezoNoTone);
|
||||
|
||||
// for real-time communication is deprecated and not recommended
|
||||
// use other protocol like websocket instead
|
||||
|
24
test/serial/piezo.ts
Normal file
24
test/serial/piezo.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Board, Piezo } from "johnny-five";
|
||||
|
||||
const board = new Board({
|
||||
port: '/dev/ttyUSB0',
|
||||
repl: false
|
||||
});
|
||||
|
||||
board.on('ready', () => {
|
||||
const piezo = new Piezo(11);
|
||||
|
||||
let ins = 0;
|
||||
|
||||
board.loop(500, async () => {
|
||||
piezo.play({
|
||||
song: "C4",
|
||||
beats: 1/2,
|
||||
tempo: 100
|
||||
})
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
piezo.note("C4", 100);
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
piezo.tone(262 * 7.3, 100);
|
||||
})
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user