19 okt

Kommentarer lukket til Underlimet vask i laminatbordplade

Underlimet vask i laminatbordplade

Af

Kan man selv underlime en køkkenvask i en laminatbordplade? “Nej”, runger det hult når man spørger på Internettet og andre steder. Men hvor mange har egentligt forsøgt sig med dette projekt? Angiveligt ikke mange, og en af grundene er nok, at det er temmelig sparsomt med oplysninger om hvordan man egentligt gør det.

Da jeg havde besluttet at udskifte min efterhånden hærgede køkkenbordplade, og at den ny løsning skulle være en laminatbordplade med underlimet vask og at jeg tilmed selv ville montere vasken, var første opgave derfor at researche og lægge en plan.

En laminatbordplade er som bekendt en forholdsvis tyk spånplade med et tyndt lag pålimet højtrykslaminat på oversiden. Princippet i en underlimet vask er at vaskens flange er limet direkte på undersiden af laminatet. For at kunne lime vasken fast på undersiden af laminaten, må der altså fra undersiden af bordpladen fjernes noget af spånpladen, og fritlægge en del af laminaten, hvorpå vasken limes fast. I princippet lyder dette måske ikke så kompliceret, men der er alligevel mange måder man kan forestille sig at gøre det på.

Efter mange overvejelse blev min plan følgende:

  1. Skær et hul i bordpladen, som er er lidt mindre (10-20 mm) end vaskens indre mål.
  2. Ved hjælp af skabelon og skabelonfræsejern fræses ud efter vaskens ydre mål fra undersiden af bordpladen, således at kun laminatet bliver tilbage.
  3. Vaskens flange limes fast på undersiden af laminatet og der pålimes understøtning i falsen i bordpladen.
  4. Udhængende laminat fræses bort fra oversiden med en kantfræser.
Princippet i underlimning af vask

Placering af vask og udskæring af hul

Som hjælpemiddel til opmærkning af placeringen af vasken og til efterfølgende fræsning havde jeg fremstillet en skabelon af 3 mm MDF plade, udskåret med laserskærer. Med skabelonen var det let at vurdere placering og opstrege til udskæring. Udskæring af det første hul er ikke så kritisk, idet det bare skal være mindre end vaskens indre mål og overskydende laminat fræses senere væk. Dette blev let udført ved at bore huller i hjørnerne og derefter save hullet med en stiksav.

Udfræsning og fritlægning af laminat

Udfræsning og fritlægning af laminat fra undersiden af bordpladen var nok den mest nervepirrende del af projektet da jeg ikke var sikker på hvordan laminatet vill opføre sig under fræsningen. Første udfording blev at hæve skabelonen 6 mm, således at afstand mellem laminat og skabelon passede med højden på skabelonjernets skær. Dette blev klaret med stumper af 6 mm MDF og masser af dobbeltklæbende tape.

Udfræsningen startede med frihåndsfræsning i progressive dybder, og det blev hurtigt klart, at det var nødvendigt at have støtte i midten af hullet. Udskæringen fra hullet blev derfor lagt i som støtte, som overfræserens land kunne glide på.

Da udfræsningen nærmede sig undersiden af laminaten, skulle der gåes forsigtigt til værks, og på trods af agtpågivenhed, så blev der lavet lidt mærker i undersiden af laminaten, men dette var af mindre betydning, så længe laminaten ikke blev gennembrudt. Limfugen udfylder udjævnhederne uden problemer. Værre var det, at kanten af laminaten også fik nogle hakker, men til alt held var disse hakker med nød og næppe begrænset til udhænget af laminat, som alligevel senere skulle fræses bort.

Det lykkedes at lave en tilfredsstillende udfræsning, men skulle jeg gøre det igen, så ville fræse en rende til fritlægning af laminaten, og først bagefter fjerne midten. På den måde vil der være mere stabil understøtning til overfræseren.

Man vil i øvrigt sikkert kunne fritlægge laminaten uden brug af skabelon. Da der fræses i undersiden af bordpladen, vil udfræsningen altid være skjult og frihåndsfræsning med sikker hånd vil sikkert være muligt. Den eneste udfræsning, der i princippet bliver synlig, er den sidste kantfræsning af laminatudhænget og her er det vaskens inderkant der følges med kantfræsejernet.

Limning af vasken

Vasken skulle nu limes fast til laminaten, og til dette havde jeg valgt West System G/FLEX 650 epoxy. Både underside af laminat og flange på vasken blev slebet med sandpapir for at skabe en ru overflade, som epoxyen kunne binde til, og herefter aftørret med isopropylalkohol for at fjerne støv og affedte. På indersiden af vasken blev der sat tape for at undgå at udklemt epoxy hæftede på indersiden af vasken. Epoxyen blev blandet og desuden afgasset i vakuum. Det sidste var nok ikke strengt nødvendigt, men jeg ville gerne forsøge at undgå luftbobler i limfugen.

Efter limning af flange mod laminat, blev lister limet i falsen for at støtte vasken nedefra. Limning alene mod laminaten vil muligvis kunne give problemer, da laminat eller limfuge ikke nødvendigvis vil være stærk nok til at holde vasken på plads under mange års brug. Listerne blev holdt på plads af stykker af transportskum.

Kantfræsning af laminat

Epoxyen var hærdet og det store øjeblik var oprundet, hvor bordpladen skulle vendes rundt og det først indtryk af udfaldet kunne vurderes. Vasken blev hængende og alt var godt.

Efter at have set splinter flyve af laminaten under fritlægningen var jeg betænkelig ved hvordan laminaten ville opføres sig under kantfræsning og indledningsvis satte jeg malertape på laminaten. Det viste sig at være unødvendigt, da fræsningen gik fuldstændig uproblematisk: Kantfræsejernet skar de fineste spåner. Afslutningsvis blev der fræset med et 45° affasningsjern og her var udfordringen at fræse så tæt på vasken uden at jernets skær ramte vasken. Det skete et enkelt sted, men dog bemærkelsesværdigt uden at jernet tog skade. Som sidste finish, blev kanten slebet og afrundet let med fint sandpapir.

Resultatet

Udfaldet af projektet blev faktisk som forventet, så alt i alt var det en succesoplevelse. Men som oftest med denne slags opgaver, så ender man med et voldsomt tidsforbrug, og selvom man på papiret har sparet penge, så gælder det helt sikkert ikke hvis man medregner sin egen timeløn.

Det store spørgmål er nu hvor godt vasken holder i brug gennem mange år. Mest kritisk er nok om limfugen mellem vask og laminat holder tæt, for hvis først der begynder at sive fugt ind her, så tager spånpladen hurtigt skade.

Indtil videre nyder jeg, at krummer på bordet, med en enkelt elegant håndbevægelse kan fejes ned i vasken.

Gemt under: Projekter

12 okt

0 Comments

Fra tungt træk til lette skridt: Carlsvognen med el, det er et hit

Af

I august 2022 total-renoverede jeg min gamle Long John og den har nu tjent mig godt de sidste tretten måneder. Jeg måtte dog indse at den er temmelig tung, især når den benyttes til sit formål; at transportere tunge ting (eller mennesker).

Jeg havde, som den vågne læser måske mindes, allerede tiltænkt at cyklen skulle have ydelses-fremmende midler monteret. Modellen Tongsheng TSDZ2B var også bestemt på daværende tidspunkt så røret der blev svejset på omkring krankboks havde rigeligt med luft til netop denne krankmotor.
Valget faldt på denne type motor, da de yder proportionelt med den effekt man selv smider i pedalerne ved hjælp af en torque-sensor i kranken.

Det giver en mere naturlig cykeloplevelse kontra typiske nav-motorer, der hjælper med en konstant effekt når der trædes i pedalerne. Ydermere, siges det at krankmotorer holder længere end nav-motorer da de arbejder for det meste i deres foretrukne omdrejningstal (30-90 rpm ved output), fremfor i hele spændet af omdrejninger et givent cykelhjul måtte have og dertil direkte gearet.

Monteringen sker desuden direkte igennem den eksisterende krankboks og der ydes på klingen, således at den almindelige gearing kan udnyttes. Motor og batteri blev monteret med originalt firmware i April 2023.

Der findes Open Source Firmware (OSF) til TSDZ2 motoren, i flere varianter:

Fordelen ved OSF til TSDZ2 er at opnå bedre styring af motoren så der spildes mindre varme og opnås bedre effekt samt respons. Et klassisk problem med denne motor er at konstruktionen er ringe lavet til at aflede varme, da kontaktfalde ved drivaksel er omtrent ~2 cm² og motoren ikke har anden kontakt med aluminiums-huset omkring motoren.

I foråret transporterede jeg min partner og jeg fra Aalborg Øst til Støvring over Gug alper, hvilket den underdimensionerede rullebremse ikke var så glad for. Det resulterede i at bremsefedtet som sådan en fyldes med brændte af. Ligeledes blev motoren ubehagelig varm på dens originale firmware, der er sat til 750w i maks effekt. Det er sandsynligvis der, hvor den første varmeskade skete.
Siden da, har effekten af motoren føles mindre, den bliver hurtigere varm, og den originale rækkevidde på ~80km er nu ca. halveret. Det er netop det forløb og symptomer som ligesindede på e-bike forummet https://endless-sphere.com/ oplever.

Bedre sent end aldrig fik jeg monteret en LM35DZ (outputter 10mV/C) analog temperaturføler på thumb-throttle ADC kanalen på den originale controller. Emmebrusas OSF kan bruge denne indgang til at læse motor-temperatur og derved gradvist regulere temperaturen ned, som den når 85C. Forinden dette har jeg også kommet thermal pads og kølefedtstof i det 1.5mm hulrum der er at finde mellem motorflade ved drivaksel og motorhus.

Resultatet er marginalt bedre køling og beskyttelse af en allerede beskadiget motor. Efter 5 kilometers kørsel i de aalborgensiske bakker rammes de 85C. Det efterlader et valg mellem den stærkere torque-sensing mid-drive motor som den nye ToSeven DM01 (pendant til Bafangs BBSHD 1kW motor) eller forsætte på TSDZ2 platformen med de begrænsninger og nødvendige eftermonteringer som det påkræver. Desværre er DM01 motoren ikke rigtig til at anskaffe i EU/US pga. manglende distribution, dog er ToSevens ingeniører at finde på forskellige fora, og sælger til enkeltpersoner. På den anden side koster en ny motor til TSDZ2 kun 450DKK – fortsættelse følger.

Fra august 2022 til april 2023 anslår jeg at cyklen har kørt ~1000km. Fra montering af motor i april 2023 og til oktober 2023 siger odometeret 1350km (-5% pga. fejlvisning).

Dansk lovgivning omkring hjælpemotor på almindelige cykler er kort opridset:

  • Motor må kun yde, når cyklist træder i pedalerne.
  • Motor på ikke yde når hastighed er over 25 km/t, derefter er det kun rugbrødmotor.
  • Motor må ikke yde mere end 250W effekt nominelt.

Overstående er fornuftigt når man ser på personcykler; altså city-bikes og lignende. Det er ikke hensigtsmæssigt at el-cykler accelerer kraftigere eller cykler hurtigere end det normale cyklist-trafikbillede. Dog er det tydeligt at på en ladcykel som min med op til 100kg i laddet, 80kg i sadlen, og ~35kg i stellet, så er den hjælp ikke voldsom – og bestemt ikke op ad bakker.

Jeg ønsker en ændring i lovgivningen der skelner mellem en 6kg kulfiber-racercykel og et 79 år gammelt, tungt ladcykelstel. Dette især hvis man ønsker at fordre alternative transportmetoder end bil for ens borgere i by-miljøer.

Min oplevelse med el-motor på min ladcykel er enormt positiv. Carlsvognen har nærmest samme fleksibilitet som en bil, til en fraktion af udgifterne – og som vist, kan rigtig mange transportopgaver nemt løses.

18 jul

0 Comments

Fantus-button part 1: Reverse engineering the DRTV Chromecast App

Af

I want to build a physical giant red button, that when pressed instantly starts a children’s TV-show, in my case Fantus on DRTV using a Chromecast.

The first part of the build is figuring out how to remotely start a specific video on a Chromecast. Initially I thought this would be pretty simple to do from an Arduino, because back in the day you could start a video just using a HTTP request. Very much not so anymore: the Chromecast protocol has evolved into some monster using JSON inside Protobuf over TLS/TCP, with multicast DNS for discovery. Chance of getting that working on a microcontroller is near-zero.

But remote control is possible using e.g. pychromecast which has support for not only the usual app of YouTube, but also a couple of custom ones like BBC. Let’s try and add support for DRTV to pychromecast, starting at the hints given on adding a new app.

Using the netlog-viewer to decode the captured net-export from Chrome, and looking at the unencrypted socket communication, the appId of the DRTV app is easily found.

However, one of the subsequent commands has a lot more customData than I expected, since it should more or less just be the contentId that is needed:

{
  "items": [
    {
      "autoplay": true,
      "customData": {
        "accountToken": {
          "expirationDate": "2022-07-02T00:48:35.391Z",
          "geoLocation": "dk",
          "isCountryVerified": false,
          "isDeviceAbroad": false,
          "isFallbackToken": false,
          "isOptedOut": false,
          "profileId": "c4e0...f3e",
          "refreshable": true,
          "scope": "Catalog",
          "type": "UserAccount",
          "value": "eyJ0eX...Dh8kXg"
        },
        "chainPlayCountdown": 10,
        "profileToken": {
          "expirationDate": "2022-07-02T00:48:35.389Z",
          "geoLocation": "dk",
          "isCountryVerified": false,
          "isDeviceAbroad": false,
          "isFallbackToken": false,
          "isOptedOut": false,
          "profileId": "c4e0a...f3e",
          "refreshable": true,
          "scope": "Catalog",
          "type": "UserProfile",
          "value": "eyJ0eXAi...IkWOU5TA"
        },
        "senderAppVersion": "2.211.33",
        "senderDeviceType": "web_browser",
        "sessionId": "cd84eb44-bce0-495b-ab6a-41ef125b945d",
        "showDebugOverlay": false,
        "userId": ""
      },
      "media": {
        "contentId": "278091",
        "contentType": "video/hls",
        "customData": {
          "accessService": "StandardVideo"
        },
        "streamType": "BUFFERED"
      },
      "preloadTime": 0,
      "startTime": 0
    }
  ],
  "repeatMode": "REPEAT_OFF",
  "requestId": 202,
  "sessionId": "81bdf716-f28a-485b-8dc3-ac4881346f79",
  "startIndex": 0,
  "type": "QUEUE_LOAD"
}

Here I spent a long time trying without any customData, and just using the appId and contentId. Initially it seemed to work!

However, it turned out it only worked if the DRTV Chromecast app was already launched from another device. If launched directly from pychromecast the app would load, show a spinner, and then go back to idle. Here much frustration was spent; I guess the customData is actually needed. And indeed, putting that in works! But where do these tokens come from, and how do we get those tokens from Python?

Using Chrome’s developer tools (F12) on the DRTV page, and then searching globally (CTRL-SHIFT-f) for various terms (“expirationDate”, “customData”, “profileToken”, “accountToken” etc.) revealed some interesting code, that was as semi-readable as any pretty-printed minifyed Javascript. Eventually I found the tokens in local storage:

Using these tokens work really well, and allows starting playback!

Some further exploration proceeded: using the showDebugOverlay flag reveals that the DRTV player is just a rebranded Shaka Player. The autoplay functionality can be disabled by setting chainPlayCountdown to -1, which is honestly a real oversight that it cannot be disabled officially, to not have to rush to stop the playback of the item before the next autoplays.

With all the puzzle pieces ready, I prepared a pull request (still open) to add support for DRTV to pychromecast.

Fantus-button part 2 will follow, detailing the hardware build and network integration with the support from pychromecast.

Gemt under: Extern, HAL9k

Tags:

20 feb

0 Comments

Floating Solid Wood Alcove Shelves

Af

I have an alcove where I wanted to put in some floating shelves. I wanted to use some solid wood I had lying around, to match the rest of the interior; this ruled out most of the methods described online: (i) building up the shelf around a bracket, and (ii) using hidden mounting hardware would be hard to get precise and would not provide support on the sides.

So inspired by some of the options instead I tried to get by with just brackets on the three sides, in a solid wood shelf. I ended up with 12mm brackets of plywood in a 26mm solid wood shelf, and that was plenty sturdy.

Step 1 was to cut out the rough shelves, with plenty of extra width, and rough fitting the plywood bracket pieces. It makes sense to leave as much on the top of the slit as possible, as this will be the failure point if overloaded. The excellent wood workshop at Hal9k came in very handy!

Step 2 was to mount the plywood brackets in the alcove. Pretty easy to do using a laser level, biggest problem was getting the rawplugs in precise enough for the level to be kept.

Step 3 was fitting the shelves individually, accounting for the crookedness of the 3 walls. The scribing method used by Rag’n’Bone Brown was pretty useful, just doing it in multiple steps to make sure not to cut off too much.

Finally, all the shelves in final mounting. Getting them in took a bit of persuasion with a hammer, and minor adjustments with a knife to the plywood brackets, as it was a tight fit. The key again was small adjustments.

One concern with such a tight fit would be wood movement; however most of the wood movement is “across the grain” which in this application means “in and out” from the alcove, where the wood is basically free to move as the shelves are not fastened to the brackets in any way.

Another concern would be if the relatively small brackets (12x12mm) can handle the load of the relatively wide shelves (60cm wide, 35cm deep, and 2.6cm high). There are two failure scenarios: (i) the wood could split above the slit, (ii) or the bracket could deform or be pulled out. Neither seems likely as (i) applying a static (or even dynamic) load large enough to split the wood seems implausible, even at the weakest point in the middle of the front, and (ii) the tight fit counteracts the brackets ability to be pulled out since pulling out in one side would have the shelf hitting the wall on the opposite side.

All in all a very satisfying project to work on and complete!

Gemt under: Extern, HAL9k

Tags: ,

15 dec

0 Comments

Quick and dirty Lithium battery-powered Wemos D1 Mini

Af

The Wemos D1 Mini is an ESP8266 based prototyping board with WiFi connectivity and countless applications. It becomes even more useful in battery-powered applications, where with the proper setup, it can run low-powered for months at a time — or only hours if done incorrectly.

This is the quick and dirty guide to running a Wemos D1 Mini powered by Lithium-Ion batteries: We will be blatantly ignoring several design specifications, so double check everything before using in a critical project. Several things will vary, and since there is plenty of clones of the board some boards will work better than others.

Warning: Lithium-Ion batteries always command healthy respect, due to the energy they store! Do not use bad cells, and do not leave batteries unattended in places where a fire can develop, especially while charging. That being said, the setup given here should be as safe as most other Lithium-Ion battery projects.

Why run off a battery?

You chose a Wemos D1 because you want to do some WiFi connectivity. This narrows down the useful modes from the overwhelming large table of possibilities. The approach will be slightly different depending on why you want to run off a battery. There are 3 main usecases:

  • Periodically wake up on a timer, do some work, connect to WiFi, and go back to sleep. Here we can utilize the deep sleep mode of the ESP8266, and get lifetimes in months.
  • Wake up based on an external pin trigger, do some work, connect to WiFi, and go back to sleep. Here we can also utilize deep sleep, and get lifetimes in weeks/months.
  • React with low latency to an external pin, do some work, and go to sleep while still connected to WiFi. Here we can utilize light sleep, but only get lifetimes in hours/days.

Hardware setup

The hardware needed is:

  • Wemos D1 Mini
  • TP4056 module with “discharge protection”, most modules with more than one chip has this, but be careful!
  • Lithium-Ion battery, e.g. a 18650 cell, and probably a holder for the battery

What you don’t want is anything resembling a power bank or battery shield with a regulated output (5V or 3V). These are practically useless, simply a more expensive battery holder! Two reasons: poorly built (I have several where standby is prevented by pulling 100 mA through a resistor!), and you don’t want a switching mode power supply. The keyword here is “quiescent current”: an SMPS can easily consume 5-10 mA continuously, which could very likely be the majority of the current draw.

Wiring diagram.

Waking on a timer – deep sleep

Full code example for deep sleeping on a timer.

To start deep sleep for a specified period of time:

//Sleep for some time; when waking everything will be reset and setup() will run again
ESP.deepSleep(30 * MICROSECONDS_PER_SEC);

Note that you can’t safely sleep for more than approximately 3 hours. Power usage is approx 0.3–0.4mA when deep sleeping.

Keep in mind that after waking from the timer the chip will be reset, meaning no state is available, and WiFi will have to reconnect. Reconnecting to WiFi can be anything from 3–10 seconds or even longer, meaning that will be a delay before the program can resume.

Waking on an pin trigger (reset)

Full code example for deep sleeping waiting for a pin trigger.

The code is exactly the same as waking on a timer, with one exception:

//Sleep until RESET pin is triggered
ESP.deepSleep(0);

The chip will be effectively Cinderella’ed, sleeping until a RESET is triggered. Same caveats apply: waking up the program is restarted, and reconnecting to WiFi will be a delay.

Stay connected – low latency

Full code example for light sleeping connected to WiFi waiting for a pin trigger. Note that the button should be connected to D3 for this example, not RST.

The key parts are:

void setup() {
  ...
  WiFi.setSleepMode(WIFI_LIGHT_SLEEP, 3);  // Automatic Light Sleep
}

void loop() {
  ...
  delay(350); // Any value between 100--500 will work, higher value more power savings
    // but also slower wakeup!
}

Simply delaying will bring power savings — simple and easy!

When awake power consumption is around 75mA. Average power consumption when light sleeping with delay(200) is around 45 mA, with delay(350) and larger is around 30–40mA.

Measuring battery depletion

The ESP can measure it’s internal VCC supply voltage, and because the battery will start dropping below the rated 3.3V before it is depleted, this allows to get an warning when the battery starts to deplete.

ADC_MODE(ADC_VCC);

void loop() {
  if (ESP.getVcc() < 2800) {
    //Do something to warn of low battery
  }
}

In my experience the Vcc reading will drop below 2800 when the battery starts to be depleted.

ADC readings vs. battery voltage

Note that measuring the VCC while connected with USB is not possible, as the USB connection will pull up the battery and the 5V rail to 5V!

Calculating battery life

Here is a quick calculator for how long your Wemos D1 Mini can stay powered




Deep sleep


(conservatively assumes base load 1mA, 10 secs burst of 100mA for every wakeup), resulting in

-

Light sleep


-

Of course the consumption can be brought even lower: some chips are unused but partly connected and will have some leakage (LEDs, USB chip on the Wemos). Making it even leaner is outside the scope of quick and dirty.

Gemt under: Extern, HAL9k