Skip to content

Commit 14c0f97

Browse files
committed
Merge branch 'main' of https://github.com/hackclub/blot
2 parents e0e6f0e + 0753380 commit 14c0f97

File tree

311 files changed

+230346
-162034
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

311 files changed

+230346
-162034
lines changed

.github/workflows/astro.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Sample workflow for building and deploying an Astro site to GitHub Pages
2+
#
3+
# To get started with Astro see: https://docs.astro.build/en/getting-started/
4+
#
5+
name: Deploy Astro site to Pages
6+
7+
on:
8+
# Runs on pushes targeting the default branch
9+
push:
10+
branches: ["main"]
11+
12+
# Allows you to run this workflow manually from the Actions tab
13+
workflow_dispatch:
14+
15+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
16+
permissions:
17+
contents: read
18+
pages: write
19+
id-token: write
20+
21+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
22+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
23+
concurrency:
24+
group: "pages"
25+
cancel-in-progress: false
26+
27+
env:
28+
BUILD_PATH: "./astro" # default value when not using subfolders
29+
# BUILD_PATH: subfolder
30+
31+
jobs:
32+
build:
33+
name: Build
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v3
38+
- name: Detect package manager
39+
id: detect-package-manager
40+
run: |
41+
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
42+
echo "manager=yarn" >> $GITHUB_OUTPUT
43+
echo "command=install" >> $GITHUB_OUTPUT
44+
echo "runner=yarn" >> $GITHUB_OUTPUT
45+
exit 0
46+
elif [ -f "${{ github.workspace }}/package.json" ]; then
47+
echo "manager=npm" >> $GITHUB_OUTPUT
48+
echo "command=ci" >> $GITHUB_OUTPUT
49+
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
50+
exit 0
51+
else
52+
echo "Unable to determine package manager"
53+
exit 1
54+
fi
55+
- name: Setup Node
56+
uses: actions/setup-node@v3
57+
with:
58+
node-version: "16"
59+
cache: ${{ steps.detect-package-manager.outputs.manager }}
60+
cache-dependency-path: ${{ env.BUILD_PATH }}/package-lock.json
61+
- name: Setup Pages
62+
id: pages
63+
uses: actions/configure-pages@v3
64+
- name: Install dependencies
65+
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
66+
working-directory: ${{ env.BUILD_PATH }}
67+
- name: Build with Astro
68+
run: |
69+
${{ steps.detect-package-manager.outputs.runner }} astro build \
70+
--site "${{ steps.pages.outputs.origin }}" \
71+
--base "${{ steps.pages.outputs.base_path }}"
72+
working-directory: ${{ env.BUILD_PATH }}
73+
- name: Upload artifact
74+
uses: actions/upload-pages-artifact@v2
75+
with:
76+
path: ${{ env.BUILD_PATH }}/dist
77+
78+
deploy:
79+
environment:
80+
name: github-pages
81+
url: ${{ steps.deployment.outputs.page_url }}
82+
needs: build
83+
runs-on: ubuntu-latest
84+
name: Deploy
85+
steps:
86+
- name: Deploy to GitHub Pages
87+
id: deployment
88+
uses: actions/deploy-pages@v2

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ node_modules
55
.next
66
astro/.astro/types.d.ts
77
.astro
8-
.vercel
8+
.vercel
9+
*/node_modules

astro/.prettierignore renamed to .prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ package-lock.json
33
public/*
44
.next/*
55
.vercel/*
6+
*/.vercel
67
*/*/*.mdx
78
*/*/*/*.mdx
File renamed without changes.

ASSEMBLY.md

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,17 @@ Blot instructions
22
---
33
Below is a list of all parts needed to construct your Blot. Keep in mind that the colors shown below are not representative of the actual color of the components. The components are colored differently to ease differentiation when going through these instructions.
44

5-
|Part |quantity |image
6-
|----------------------|----|---
7-
|M5x30 |? |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/0image0056.png" alt="aaa" width="100"/>
8-
|M5x20 |? |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/2image0058.png" alt="aaa" width="100"/>
9-
|M5x10 |? |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/3image0059.png" alt="aaa" width="100"/>
10-
|M3x10 |8 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/1image0057.png" alt="aaa" width="100"/>
11-
|Shim |? |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/4image0060.png" alt="aaa" width="100"/>
12-
|Eccentric<br>Spacer|5 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/8image0055.png" alt="aaa" width="100"/>
13-
|Spacer |? |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/5image0061.png" alt="aaa" width="100"/>
14-
|V-Wheel |8 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/6image0053.png" alt="aaa" width="100"/>
15-
|Idler bearing |10 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/7image0054.png" alt="aaa" width="100"/>
16-
|Timing Belt<br>Pulley |2 |<img src="https://cloud-ailzl7xby-hack-club-bot.vercel.app/1image0068.png" alt="aaa" width="100"/>
17-
|Rubber<br>Feet |4 |<img src="" alt="aaa" width="100"/>
18-
|Carriage |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/0image0062.png" alt="aaa" width="100"/>
19-
|Tool Head |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/1image0063.png" alt="aaa" width="100"/>
20-
|Printed Rail |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/2image0064.png" alt="aaa" width="100"/>
21-
|Motor Leg |2 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/3image0065.png" alt="aaa" width="100"/>
22-
|Belt Clip |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/4image0066.png" alt="aaa" width="100"/>
23-
|Stepper<br>Motor |2 |<img src="https://cloud-ailzl7xby-hack-club-bot.vercel.app/0image0067.png" alt="aaa" width="100"/>
5+
|Part |Quantity |Image||Part|Quantity|Image
6+
|----------------------|-----|-|-|-|-|-
7+
|M5x35 |11 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/0image0056.png" alt="aaa" width="100"/>||Timing Belt<br>Pulley |2 |<img src="https://cloud-ailzl7xby-hack-club-bot.vercel.app/1image0068.png" alt="aaa" width="100"/>
8+
|M5x20 |6 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/2image0058.png" alt="aaa" width="100"/>||Rubber<br>Feet |4 |<img src="https://cloud-hma32kk1l-hack-club-bot.vercel.app/6image0078.png" alt="aaa" width="100"/>
9+
|M5x10 |14 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/3image0059.png" alt="aaa" width="100"/>||Carriage |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/0image0062.png" alt="aaa" width="100"/>
10+
|M3x10 |8 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/1image0057.png" alt="aaa" width="100"/>||Tool Head |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/1image0063.png" alt="aaa" width="100"/>
11+
|Shim |5 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/4image0060.png" alt="aaa" width="100"/>||Printed Rail |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/2image0064.png" alt="aaa" width="100"/>
12+
|[Eccentric<br>Spacer](https://www.amazon.com/Micro-Traders-Eccentric-Aluminium-Extrusion/dp/B09CYK9P43/)|5 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/8image0055.png" alt="aaa" width="100"/>||Motor Leg |2 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/3image0065.png" alt="aaa" width="100"/>
13+
|Spacer |4 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/5image0061.png" alt="aaa" width="100"/>||Belt Clip |1 |<img src="https://cloud-dxz9fnfpj-hack-club-bot.vercel.app/4image0066.png" alt="aaa" width="100"/>
14+
|V-Wheel |8 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/6image0053.png" alt="aaa" width="100"/>||Stepper<br>Motor |2 |<img src="https://cloud-ailzl7xby-hack-club-bot.vercel.app/0image0067.png" alt="aaa" width="100"/>
15+
|Idler bearing |10 |<img src="https://cloud-agax6w6e0-hack-club-bot.vercel.app/7image0054.png" alt="aaa" width="100"/>||Servo|1|
2416

2517
---
2618
Carriage assembly
@@ -104,6 +96,10 @@ Insert a motor into the motor mount, with its cable facing away from the legs, a
10496
<img src="https://cloud-nzd74pzqy-hack-club-bot.vercel.app/1image0018.png" alt="aaa" width="300"/><br>
10597
Screw the motor in place with 4 m3x10 screws. Do this assembly twice, once for each leg.
10698

99+
---
100+
<img src="https://cloud-hma32kk1l-hack-club-bot.vercel.app/5image0077.png" alt="aaa" width="300"/><br>
101+
Attach rubber feet to the bottom of the legs.
102+
107103
---
108104
Printed rail assembly
109105
---
@@ -144,7 +140,7 @@ Your final toolhead assembly should now look like this.
144140
Final assembly
145141
---
146142
<img src="https://cloud-8faenwnrg-hack-club-bot.vercel.app/0image0028.png" alt="aaa" width="300"/><br>
147-
Insert one aluminum extrusion into one of your leg assemblies.
143+
Insert one aluminum extrusion into one of your leg assemblies. *Be careful as it may require some force.*
148144

149145
---
150146
<img src="https://cloud-8faenwnrg-hack-club-bot.vercel.app/1image0029.png" alt="aaa" width="300"/><img src="https://cloud-8faenwnrg-hack-club-bot.vercel.app/2image0030.png" alt="aaa" width="300"/><br>
@@ -164,11 +160,11 @@ Attach the carriage onto the rail with the belt bearings facing upwards. *Should
164160

165161
---
166162
<img src="https://cloud-8faenwnrg-hack-club-bot.vercel.app/8image0036.png" alt="aaa" width="300"/><br>
167-
attach the other leg, enclosing the carriage between both legs.
163+
attach the other leg, enclosing the carriage between both legs. *Be careful as it may require some force.*
168164

169165
---
170166
<img src="https://cloud-6lmi5hoqv-hack-club-bot.vercel.app/0image0037.png" alt="aaa" width="300"/><br>
171-
Attach the printed rail to one side of the other aluminum extrusion.
167+
Attach the printed rail to one side of the other aluminum extrusion. *Be careful as it may require some force.*
172168

173169
---
174170
<img src="https://cloud-6lmi5hoqv-hack-club-bot.vercel.app/1image0038.png" alt="aaa" width="300"/><img src="https://cloud-6lmi5hoqv-hack-club-bot.vercel.app/2image0039.png" alt="aaa" width="300"/><br>
@@ -190,7 +186,7 @@ Insert the rail into the top of the carriage. Then, flip the blot over so that i
190186

191187
<img src="https://cloud-i3kx1iw0w-hack-club-bot.vercel.app/0image0045.png" alt="aaa" width="300"/>
192188
<img src="https://cloud-i3kx1iw0w-hack-club-bot.vercel.app/2image0047.png" alt="aaa" width="300"/><br>
193-
Next, we need to attach the belt clip. Make sure it is flush with the aluminum extrusion.
189+
Next, we need to attach the belt clip. Make sure it is flush with the aluminum extrusion. *Be careful as it may require some force.*
194190

195191
---
196192
<img src="https://cloud-hma32kk1l-hack-club-bot.vercel.app/0image0046.png" alt="aaa" width="300"/>
@@ -210,4 +206,4 @@ Create another belt bearing assembly and ensure the belt is behind it.
210206
Here comes the hardest part: routing the belt. Ensure it goes around the shafts of both motors, and runs between the belt bearings within the carriage.
211207

212208
---
213-
At the belt clip, bend the belt around on itself (with the teeth facing outwards) in order to hold it tight.
209+
At the belt clip, bend the belt around on itself (with the teeth facing outwards) in order to hold it tight.

CHANGELOG.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ while (abs(motor1Step) < abs(motor1Target) || abs(motor2Step) < abs(motor2Target
3030
...
3131
}
3232
```
33-
I was finding it difficult to debug with the cobs encoded messages coming up from the device so started using cobs encoding to send messages but using new line (`0x0A`) delimiters to differentiate messages being sent back.
33+
34+
I was finding it difficult to debug with the cobs encoded messages coming up from the device so started using cobs encoding to send messages but using new line (`0x0A`) delimiters to differentiate messages being sent back.
3435

3536
The print function is useful for debugging arrays.
3637

@@ -78,7 +79,7 @@ void sendAck(uint8_t msgCount, uint8_t* reply, uint8_t length) {
7879
// printArray("ACK", byteArray, 5+length);
7980
8081
Serial.write(byteArray, arrayLength);
81-
82+
8283
// uint8_t byteArrayEncoded[arrayLength + 2]; // +2 for possible COBS overhead
8384
// cobs_encode(byteArrayEncoded, byteArray, arrayLength);
8485
// Serial.write(byteArrayEncoded, arrayLength + 2);
@@ -90,7 +91,7 @@ void sendAck(uint8_t msgCount, uint8_t* reply, uint8_t length) {
9091

9192
So far this has worked pretty well for me, but Shawn is still reporting some issues so we need to run more tests.
9293

93-
Moving on to some other parts of the project. I wrote up a [doc describing an engagement model](https://github.com/hackclub/haxidraw/blob/main/ENGAGEMENT.md) for gettine the machine.
94+
Moving on to some other parts of the project. I wrote up a [doc describing an engagement model](https://github.com/hackclub/haxidraw/blob/main/ENGAGEMENT.md) for gettine the machine.
9495

9596
Part of that model involves submitting pieces to a virtual gallery space. I decided an interesting space could be a infinite maze which gets randomly populated with submitted art work. I made a quick implementation of the maze which ended up being a classic raycasting project. Right now it's very Wolfenstein.
9697

@@ -104,40 +105,39 @@ Here is the draft interface:
104105

105106
<img width="1113" alt="Screen Shot 2023-05-26 at 10 44 05 AM" src="https://github.com/hackclub/haxidraw/assets/27078897/ca30829b-d886-4253-8fa9-216b2684c198">
106107

107-
I created two ways to make drawings. One is using the Turtle class which lets you create drawings programmatically, and two is by dropping an SVG into the editor which will automatically be converted into a Turtle. You can then use affine transformations (scale, rotate, translate) to position it properly.
108+
I created two ways to make drawings. One is using the Turtle class which lets you create drawings programmatically, and two is by dropping an SVG into the editor which will automatically be converted into a Turtle. You can then use affine transformations (scale, rotate, translate) to position it properly.
108109

109110
In the bottom right corner the editor has a little console. This was somewhat interesting to implement. I wanted it to have access to the functions in the top-level scope of the most recently run script. So you can define functions in the editor and then run them on command in the command line. I did this by rewriting the script a bit before running it.
110111

111112
Here is the relevant code:
112113

113114
```js
114-
const ast = acorn.parse(code, { ecmaVersion: "latest" });
115+
const ast = acorn.parse(code, { ecmaVersion: 'latest' })
115116

116-
const topScopeInserts = [];
117+
const topScopeInserts = []
117118

118119
ast.body.forEach(statement => {
119-
const { type } = statement;
120+
const { type } = statement
120121

121-
if (type === "VariableDeclaration") {
122+
if (type === 'VariableDeclaration') {
122123
statement.declarations.forEach(x => {
123-
topScopeInserts.push(x.id.name);
124+
topScopeInserts.push(x.id.name)
124125
})
125126
}
126127

127-
if (type === "FunctionDeclaration") {
128-
topScopeInserts.push(statement.id.name);
128+
if (type === 'FunctionDeclaration') {
129+
topScopeInserts.push(statement.id.name)
129130
}
130-
131131
})
132132

133133
topScopeInserts.forEach(name => {
134134
code += `\n;topScope["${name}"] = ${name};`
135-
});
135+
})
136136
```
137137

138138
One design consideration when making the editor is that when a user calls the `runMachine()` function it should run the drawing which is currently visible.
139139

140-
Moving on to the firmware. It took a bit of patience to implement COBS properly. Though implementing it in JavaScript recently I willfully ignored doing so for the embedded instead opting to use newline delimiters for the communication stream. The ASCII for newline is `0x0A` otherwise known as 10. 10 periodically does show up in bytesteam encodings, which was giving me some trouble. This is what COBS is for, to give you a known unique character which will occur only at the end of your messages. The challenge in implementing it is my Arduino print statements (my primary debugging technique) no longer worked because the other end of my serial communication connection in the browser was then expecting 0 delimited messages.
140+
Moving on to the firmware. It took a bit of patience to implement COBS properly. Though implementing it in JavaScript recently I willfully ignored doing so for the embedded instead opting to use newline delimiters for the communication stream. The ASCII for newline is `0x0A` otherwise known as 10. 10 periodically does show up in bytesteam encodings, which was giving me some trouble. This is what COBS is for, to give you a known unique character which will occur only at the end of your messages. The challenge in implementing it is my Arduino print statements (my primary debugging technique) no longer worked because the other end of my serial communication connection in the browser was then expecting 0 delimited messages.
141141

142142
The solution is pretty straightforward though. Just implement the encoding and decoding incrementally. So first verify I can encode and decode messages just in JS. Then send encoded messages to the firmware but expect to receive back newline delimited messages so I can read the print statements. Then when I know everything else works encode the messages coming back up and decode them in JS.
143143

@@ -161,9 +161,9 @@ I acquired some Gelly Roll Sakura pens which I used to make some of our most int
161161
I made the JS controls function asyncronously by adding a number ID to each message and sending back acknowledgements. This allows us to write code like such:
162162

163163
```js
164-
const port = await createWebSerialPort(rawPort);
165-
const bytes = floatsToBytes([ x, y ]);
166-
await port.send("go", bytes);
164+
const port = await createWebSerialPort(rawPort)
165+
const bytes = floatsToBytes([x, y])
166+
await port.send('go', bytes)
167167
```
168168

169169
in which the machine actually executes and finishes the command before the await resolves.
@@ -227,21 +227,21 @@ It looks like we'll be using the single control board designed for the drawing m
227227
- We should still be able to interface with the machine in high-level languages as a virtual object.
228228
- The motor control should be good
229229
230-
These two goals and our approaches to addressing them are heavily influenced by the work we did the Modular Things project. For the first goal we need to define a communication interface. Almost like a REST API for the machine (if you're coming from the web dev world).
230+
These two goals and our approaches to addressing them are heavily influenced by the work we did the Modular Things project. For the first goal we need to define a communication interface. Almost like a REST API for the machine (if you're coming from the web dev world).
231231
232232
Motor control is a tricky topic. Historically most digital fabrication machines have been built around [GRBL](https://github.com/grbl/grbl) recently [Klipper3D](https://www.klipper3d.org/) has risen in popularity.
233233
234-
The basic problem is about figuring out how to turn multiple motors who's collective motion results in the movement of the machine in a controlled manner. In the case of our machine we have two motors which are coupled together through a belt.
234+
The basic problem is about figuring out how to turn multiple motors who's collective motion results in the movement of the machine in a controlled manner. In the case of our machine we have two motors which are coupled together through a belt.
235235
236236
In short I managed to write a fairly low quality motion controller (but a functional one) which has constant speed. Preferably we would set maximum accelerations and the planner would figure out the appropriate speeds based on the path it needs to take. But we'll build up to that in the coming weeks. We are sending out machines to testers and developers now so we need to have a nice interface for people to develop devices.
237237
238238
Something like this:
239239
240240
```js
241-
import { createHaxidraw } from "createHaxidraw.js";
241+
import { createHaxidraw } from 'createHaxidraw.js'
242242
243-
await haxidraw.servo(-90);
244-
await haxidraw.moveTo(x, y);
243+
await haxidraw.servo(-90)
244+
await haxidraw.moveTo(x, y)
245245
```
246246

247247
This is a virtual machine which communicates with the actual machine through the serial port.

0 commit comments

Comments
 (0)