stable lcd scrolling

This commit is contained in:
Boaz Sender 2025-03-31 10:04:57 -07:00
parent 0e7c1b080d
commit 869e1e574c
5 changed files with 108 additions and 32 deletions

View file

@ -1,23 +1,52 @@
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
import LCD from "raspberrypi-liquid-crystal";
const timer = (ms) => new Promise((res) => setTimeout(res, ms));
const lcd = new LCD(1, 0x27, 16, 2);
const tag = " Black Portal 1234 E Davison, Detroit Michigan";
lcd.beginSync();
lcd.clearSync();
lcd.printSync('Black');
lcd.setCursorSync(0, 1);
lcd.printSync('Portal');
setInterval(async () => {
let tagCount = 0;
setInterval(() => {
lcd.printLineSync(1, " ");
setTimeout(() => {
lcd.printLineSync(1, tag.substring(tagCount, 16 + tagCount));
}, 50);
tagCount++;
if (tagCount > tag.length) {
tagCount = 0;
}
}, 500);
const getStanza = async () => {
const stanzaCount = await prisma.stanza.count();
const skip = Math.floor(Math.random() * stanzaCount);
const randomStanza = await prisma.stanza.findMany({
take: 1,
skip: skip,
take: 1,
});
if (randomStanza) {
lcd.clearSync();
lcd.printSync(randomStanza[0].text.substring(0, 16));
lcd.setCursorSync(0, 1);
lcd.printSync(randomStanza[0].text.substring(16, 32));
return randomStanza[0].text;
};
let stanza = await getStanza();
while (true) {
let outerInterval;
let innerInterval;
if (stanza) {
let characterLocation = 0;
outerInterval = setInterval(async () => {
lcd.printLineSync(0, " ");
innerInterval = setTimeout(() => {
lcd.printLineSync(0, `${16 - characterLocation > 0
? Array(16 - characterLocation).join(" ")
: ""}${stanza}`.substring(characterLocation, 16 + characterLocation));
}, 50);
characterLocation++;
if (characterLocation > stanza.length) {
stanza = await getStanza();
characterLocation = 0;
}
}, 700);
}
await timer((16 + stanza.length) * 750);
clearInterval(outerInterval);
clearInterval(innerInterval);
}
}, 3000);

View file

@ -1,21 +1,26 @@
# Internet radio electronics for Black Portal Detroit
# Internet radio electronics and software for Black Portal Detroit
Electronics and software for the Black Portal Detroit work By Wes Taylor for the [Code Switch show at at MOCAD](https://thekitchen.org/on-view/code-switch-distributing-blackness-reprogramming-internet-art/). Electronics and software built and written by Boaz Sender based on Wes' concept and at Wes' direction.
## Software provisioning and setup
This repository also contains documentation for how to buy and setup the electronics for Black Portal Detroit.
1. Broadcaster bill of materials and software setup instructions in [broadcaster.md](broadcaster.md)
2. Listener bill of materials and software setup instructions in [listener.md](listener.md)
## Custom software
This repository contains custom software for turning a m3u radio stream into a logic for random selection of lyrics from an sqlite database of song stanzas written by Detroiters from the neighborhood where MOCAD is.
3. Custom software development instructions in [listener-lcd-screen-software.md](listener-lcd-screen-software.md)
## Turning on the devices
4. The sequence for turning on the system is in [how-to-turn-it-on.md](how-to-turn-it-on.md)
Prior research that didn't work in `research-` md files.
## Live access
5. If everything is turned on and configured properly, you may visit https://blackportaldetroit.com to hear the broadcaster.

View file

@ -5,7 +5,7 @@
"description": "https://blackportaldetroit.com",
"main": "index.js",
"scripts": {
"build": "tsc screen.ts",
"build": "tsc",
"deploy": "npm run build && rsync -avx rsync -a --exclude-from='exclude.txt' ./ grace@listener.local:portal"
},
"repository": {

View file

@ -1,31 +1,69 @@
import { PrismaClient } from "@prisma/client";
import { PrismaClient, Stanza } from "@prisma/client";
const prisma = new PrismaClient();
import LCD from "raspberrypi-liquid-crystal"
const lcd = new LCD( 1, 0x27, 16, 2 );
import LCD from "raspberrypi-liquid-crystal";
const timer = (ms: number) => new Promise((res) => setTimeout(res, ms));
const lcd = new LCD(1, 0x27, 16, 2);
const tag = " Black Portal 1234 E Davison, Detroit Michigan";
lcd.beginSync();
lcd.clearSync();
lcd.printSync( 'Black' );
lcd.setCursorSync(0, 1);
lcd.printSync( 'Portal' );
let tagCount = 0;
setInterval(async ()=>{
setInterval(() => {
lcd.printLineSync(1, " ");
setTimeout(() => {
lcd.printLineSync(1, tag.substring(tagCount, 16 + tagCount));
}, 50);
tagCount++;
if (tagCount > tag.length) {
tagCount = 0;
}
}, 500);
const getStanza = async () => {
const stanzaCount = await prisma.stanza.count();
const skip = Math.floor(Math.random() * stanzaCount) - 1;
const skip = Math.floor(Math.random() * stanzaCount);
const randomStanza = await prisma.stanza.findMany({
take: 2,
skip: skip,
take: 1,
});
if(randomStanza){
lcd.clearSync();
if(randomStanza[0].text.length < 16){
lcd.printSync( randomStanza[0].text );
lcd.setCursorSync(0, 1);
lcd.printSync( randomStanza[1].text );
}
}
}, 3000)
return randomStanza[0].text as string;
};
let stanza = await getStanza();
while (true) {
let outerInterval;
let innerInterval;
if (stanza) {
let characterLocation = 0;
outerInterval = setInterval(async () => {
lcd.printLineSync(0, " ");
innerInterval = setTimeout(() => {
lcd.printLineSync(
0,
`${
16 - characterLocation > 0
? Array(16 - characterLocation).join(" ")
: ""
}${stanza}`.substring(characterLocation, 16 + characterLocation)
);
}, 50);
characterLocation++;
if (characterLocation > stanza.length) {
stanza = await getStanza();
characterLocation = 0;
}
}, 700);
}
await timer((16 + stanza.length) * 750);
clearInterval(outerInterval);
clearInterval(innerInterval);
}

View file

@ -1,4 +1,8 @@
{
"exclude": [
"node_modules",
"prisma"
],
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */