Modular things¶
Ref. modular-things
Install¶
(1) install [node.js](https://nodejs.org/en/) - please use version 16.15.1 or above
(2) clone this repo
(3) navigate to <this-repo>/js and do npm install in the terminal
(1) Install node.js¶
% echo $PATH
/usr/local/bin
% node --version
v19.8.1
% npm --version
9.5.1
(2) clone this repo¶
% cd repos
% git clone https://github.com/modular-things/modular-things.git
Cloning into 'modular-things'...
...
Resolving deltas: 100% (1324/1324), done.
% ls
modular-things
% cd modular-things
% ls
LICENSE.md astro.config.mjs public
README.md examples src
TODO.md log tsconfig.json
arduino package.json yarn.lock
(3) navigate to this-repo/js and do npm install in the terminal¶
There is no this-repo/js folder in this repo. (see tree below)
But there is this-repo/package.json
Notes
引数のない npm install コマンド実行をすると、カレントディレクトリにある package.json に記述されている情報を元に、そこに記述されている パッケージを node_modules (インストール先)にインストールします。
If you run the npm install command without arguments, based on the information described in package.json in the current directory, the package described there will be installed to node_modules (installation destination).
% pwd
/Users/yuichi/repos/modular-things
% tree
.
├── LICENSE.md
├── README.md
├── TODO.md
├── arduino
│ ├── accelerometer-thing
│ │ └── accelerometer-thing.ino
│ ├── capacitive-thing
│ │ └── capacitive-thing.ino
│ ├── dc-encoder-thing
│ │ └── dc-encoder-thing.ino
│ ├── mosfet-thing
│ │ └── mosfet-thing.ino
│ ├── oled-thing
│ │ └── oled-thing.ino
│ ├── potentiometer-thing
│ │ └── potentiometer-thing.ino
│ ├── rgbb-thing
│ │ └── rgbb-thing.ino
│ ├── rgbb-thing-rpc
│ │ └── rgbb-thing-rpc.ino
│ ├── rpc-mule
│ │ └── rpc-mule.ino
│ ├── servo-thing
│ │ └── servo-thing.ino
│ ├── stepper-hbridge
│ │ ├── motionStateMachine.cpp
│ │ ├── motionStateMachine.h
│ │ ├── stepper-hbridge.ino
│ │ ├── stepperDriver.cpp
│ │ └── stepperDriver.h
│ ├── stepper-hbridge-rp2040
│ │ ├── motionStateMachine.cpp
│ │ ├── motionStateMachine.h
│ │ ├── stepper-hbridge-rp2040.ino
│ │ ├── stepperDriver.cpp
│ │ └── stepperDriver.h
│ └── time-of-flight
│ └── time-of-flight.ino
├── astro.config.mjs
├── examples
│ ├── examples
│ │ ├── circleMachine.js
│ │ ├── corexy_machine.js
│ │ ├── potentiometerMachine.js
│ │ ├── sequencer.js
│ │ ├── songs
│ │ │ └── avril.txt
│ │ ├── viewWindow.js
│ │ ├── websocket_example
│ │ │ ├── client.js
│ │ │ └── server.py
│ │ ├── xylophone.js
│ │ └── xylophone_sequencer.js
│ ├── machine-interface.js
│ └── web-serial-test.html
├── log
│ ├── 2022-10_jakes-modular-thing-log.md
│ ├── 2022-11_jakes-modular-thing-motion-notes.md
│ ├── 2022-11_usb-motion-perf-tests-log.md
│ ├── 2022-12_jakes-fixed-point-log.md
│ ├── 2022-12_modular-things-oshwa-prop.md
│ ├── 2022-12_xylophone-log.md
│ ├── images
│ │ └── 2022-12-15_fixed-points-01.png
│ └── video
│ ├── mt-01-intro.mp4
│ ├── mt-02-ui.mp4
│ ├── mt-03-xylophone.mp4
│ └── mt-04-machineweek.mp4
├── package.json
├── public
│ └── machine-interface.js
├── src
│ ├── components
│ │ ├── HelpMarkdown.md
│ │ ├── ScanButton.jsx
│ │ ├── SideMenu.tsx
│ │ ├── TopMenu.jsx
│ │ ├── codemirror.tsx
│ │ └── index.jsx
│ ├── env.d.ts
│ ├── lib
│ │ ├── SAMPLES.js
│ │ ├── bundle-eval
│ │ │ ├── fs.ts
│ │ │ └── run.ts
│ │ ├── codemirror
│ │ │ └── init.ts
│ │ ├── download.js
│ │ ├── events
│ │ │ ├── addDividerDrag.js
│ │ │ └── listen.js
│ │ ├── global_state.ts
│ │ ├── init.js
│ │ ├── modularThingClient.ts
│ │ ├── osapjs
│ │ │ ├── LICENSE.md
│ │ │ ├── README.md
│ │ │ ├── core
│ │ │ │ ├── endpoint.js
│ │ │ │ ├── highLevel.js
│ │ │ │ ├── loop.js
│ │ │ │ ├── mvc.js
│ │ │ │ ├── netRunner.js
│ │ │ │ ├── osap.js
│ │ │ │ ├── packets.js
│ │ │ │ ├── query.js
│ │ │ │ ├── queryMSeg.js
│ │ │ │ ├── rpc.js
│ │ │ │ ├── time.js
│ │ │ │ ├── ts.js
│ │ │ │ ├── vertex.js
│ │ │ │ └── vport.js
│ │ │ ├── utes
│ │ │ │ ├── cobs.js
│ │ │ │ └── diff.js
│ │ │ └── vport
│ │ │ ├── vPortSerial.js
│ │ │ └── vPortWebSerial.ts
│ │ ├── runCode.js
│ │ ├── setThingsState.js
│ │ └── virtualThings
│ │ ├── TODO_breadboard.js
│ │ ├── accelerometer.js
│ │ ├── capacitive.js
│ │ ├── mosfet.js
│ │ ├── oled.js
│ │ ├── potentiometer.js
│ │ ├── rgbb.js
│ │ ├── servo.js
│ │ ├── stepper.js
│ │ ├── synchronizer.js
│ │ └── timeOfFlight.js
│ ├── pages
│ │ └── index.astro
│ └── styles
│ ├── HelpMarkdown.module.css
│ ├── SideMenu.module.css
│ ├── TopMenu.module.css
│ ├── codemirror.module.css
│ └── global.css
├── tsconfig.json
└── yarn.lock
% pwd
/Users/yuichi/repos/modular-things
% npm install
added 434 packages, and audited 435 packages in 48s
164 packages are looking for funding
run `npm fund` for details
5 high severity vulnerabilities
To address all issues, run:
npm audit fix
Run `npm audit` for details.
npm notice
npm notice New minor version of npm available! 9.5.1 -> 9.6.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.6.2
npm notice Run npm install -g npm@9.6.2 to update!
npm notice
Run¶
Run
(1) from <this-repo>/js do npm run start
(2) navigate (in the browser) to http://localhost:8080/client/
(1) do npm run start
¶
% pwd
/Users/yuichi/repos/modular-things
% npm run start
> sprig-3@1.0.0 start
> astro dev
🚀 astro v2.0.4 started in 25ms
┃ Local http://localhost:3000/modular-things/
┃ Network use --host to expose
The following dependencies are imported but could not be resolved:
serialport (imported by /Users/yuichi/repos/modular-things/src/lib/osapjs/vport/vPortSerial.js)
Are they installed?
16:48:53 [serve] 404 /favicon.ico
(2) navigate (in the browser) to http://localhost:8080/client/¶
Writing New modular-things¶
For embedded (arduino) codes, install the OSAP library, which you can download as a zip here: https://github.com/jakeread/osap-arduino, and should also be available via arduino's library manager.
Also, install the FlashStorage_SAMD library, via the library manager.
We use the ArduinoCore-fab-sam for these circuits, which you can install into Arduino via the notes in that repo.
Install the OSAP library¶
Download zip from here
Install the FlashStorage_SAMD library, via the library manager.¶
Board core¶
Board¶
there circuits¶
code¶
% pwd
/Users/yuichi/repos/modular-things/arduino
% tree
.
├── accelerometer-thing
│ └── accelerometer-thing.ino
├── capacitive-thing
│ └── capacitive-thing.ino
├── dc-encoder-thing
│ └── dc-encoder-thing.ino
├── mosfet-thing
│ └── mosfet-thing.ino
├── oled-thing
│ └── oled-thing.ino
├── potentiometer-thing
│ └── potentiometer-thing.ino
├── rgbb-thing
│ └── rgbb-thing.ino
├── rgbb-thing-rpc
│ └── rgbb-thing-rpc.ino
├── rpc-mule
│ └── rpc-mule.ino
├── servo-thing
│ └── servo-thing.ino
├── stepper-hbridge
│ ├── motionStateMachine.cpp
│ ├── motionStateMachine.h
│ ├── stepper-hbridge.ino
│ ├── stepperDriver.cpp
│ └── stepperDriver.h
├── stepper-hbridge-rp2040
│ ├── motionStateMachine.cpp
│ ├── motionStateMachine.h
│ ├── stepper-hbridge-rp2040.ino
│ ├── stepperDriver.cpp
│ └── stepperDriver.h
└── time-of-flight
└── time-of-flight.ino
Xiao RP2040¶
Board¶
stepper-hbridge | |
---|---|
Download Eagle BRD SCH(wip) |
stepper-hbridge | |
---|---|
code¶
Notes
https://github.com/earlephilhower/arduino-pico
├── stepper-hbridge-rp2040
│ ├── motionStateMachine.cpp
│ ├── motionStateMachine.h
│ ├── stepper-hbridge-rp2040.ino
│ ├── stepperDriver.cpp
│ └── stepperDriver.h
#include "motionStateMachine.h"
#include "stepperDriver.h"
#include <osap.h>
#include <vt_endpoint.h>
#include <vp_arduinoSerial.h>
#include <core/ts.h>
// ---------------------------------------------- OSAP central-nugget
// message-passing memory allocation
#define OSAP_STACK_SIZE 12
VPacket messageStack[OSAP_STACK_SIZE];
OSAP osap("stepper", messageStack, OSAP_STACK_SIZE);
// ---------------------------------------------- 0th Vertex: OSAP USB Serial
VPort_ArduinoSerial vp_arduinoSerial(&osap, "usbSerial", &Serial);
// ---------------------------------------------- 1th Vertex: Target Requests (pos, or velocity)
EP_ONDATA_RESPONSES onTargetData(uint8_t* data, uint16_t len){
uint16_t wptr = 0;
// there's no value in getting clever here: we have two possible requests...
if(data[wptr ++] == MOTION_MODE_POS){
float targ = ts_readFloat32(data, &wptr);
float maxVel = ts_readFloat32(data, &wptr);
float maxAccel = ts_readFloat32(data, &wptr);
motion_setPositionTarget(targ, maxVel, maxAccel);
} else if (data[wptr ++] == MOTION_MODE_VEL){
float targ = ts_readFloat32(data, &wptr);
float maxAccel = ts_readFloat32(data, &wptr);
motion_setVelocityTarget(targ, maxAccel);
}
return EP_ONDATA_ACCEPT;
}
Endpoint targetEndpoint(&osap, "targetState", onTargetData);
// ---------------------------------------------- 2nd Vertex: Motion State Read
// queries only, more or less, so
EP_ONDATA_RESPONSES onMotionStateData(uint8_t* data, uint16_t len){ return EP_ONDATA_REJECT; }
boolean beforeMotionStateQuery(void);
Endpoint stateEndpoint(&osap, "motionState", onMotionStateData, beforeMotionStateQuery);
uint8_t stateData[12];
boolean beforeMotionStateQuery(void){
motionState_t state;
motion_getCurrentStates(&state);
uint16_t rptr = 0;
ts_writeFloat32(state.pos, stateData, &rptr);
ts_writeFloat32(state.vel, stateData, &rptr);
ts_writeFloat32(state.accel, stateData, &rptr);
stateEndpoint.write(stateData, 12);
// in-fill current posn, velocity, and acceleration
return true;
}
// ---------------------------------------------- 3rd Vertex: Set Current Position
EP_ONDATA_RESPONSES onPositionSetData(uint8_t* data, uint16_t len){
// should do maxAccel, maxVel, and (optionally) setPosition
// upstream should've though of this, so,
uint16_t rptr = 0;
float pos = ts_readFloat32(data, &rptr);
motion_setPosition(pos);
return EP_ONDATA_ACCEPT;
}
Endpoint positionSetEndpoint(&osap, "setPosition", onPositionSetData);
// ---------------------------------------------- 4th Vertex: Settings catch-all,
EP_ONDATA_RESPONSES onSettingsData(uint8_t* data, uint16_t len){
// it's just <cscale> for the time being,
uint16_t rptr = 0;
float cscale = ts_readFloat32(data, &rptr);
stepper_setCScale(cscale);
return EP_ONDATA_ACCEPT;
}
Endpoint settingsEndpoint(&osap, "settings", onSettingsData);
// ---------------------------------------------- 5th Vertex: Limit / Switch Output... non-op at the moment,
// fair warning, this is unused at the moment... and not set-up,
// also the limit pin is config'd to look at the interrupt on a scope at the moment, see motionStateMachine.cpp
Endpoint buttonEndpoint(&osap, "buttonState");
void setup() {
Serial.begin(0);
// ~ important: the stepper code initializes GCLK4, which we use as timer-interrupt
// in the motion system, so it aught to be initialized first !
stepper_init();
// another note on the motion system:
// at the moment, we have a relatively small absolute-maximum speed: say the integrator interval is 250us,
// we have 0.00025 seconds between ticks, for a max of 4000 steps / second...
// we are then microstepping at 1/4th steps, for 800 steps per motor revolution, (from a base of 200)
// meaning we can make only 5 revs / sec, or 300 rippums (RPM),
// with i.e. a 20-tooth GT2 belt, we have 40mm of travel per revolution, making only 200mm/sec maximum traverse
// this is not pitiful, but not too rad, and more importantly is that we will want to communicate these limits
// to users of the motor - so we should outfit a sort of settings-grab function, or something ?
motion_init(250);
// uuuh...
osap.init();
// run the commos
vp_arduinoSerial.begin();
pinMode(PIN_BUT, INPUT_PULLUP);
}
uint32_t debounceDelay = 1;
uint32_t lastButtonCheck = 0;
boolean lastButtonState = false;
void loop() {
// do graph stuff
osap.loop();
// if(lastIntegration + integratorInterval < micros()){
// // stepper_step(1, true);
// lastIntegration = micros();
// motion_integrate();
// }
// debounce and set button states,
if(lastButtonCheck + debounceDelay < millis()){
lastButtonCheck = millis();
boolean newState = digitalRead(PIN_BUT);
if(newState != lastButtonState){
lastButtonState = newState;
// invert on write: vcc-low is button-down, but we should be "true" when down and "false" when up
buttonEndpoint.write(!lastButtonState);
}
}
}
Last update:
September 27, 2023