• Quick update

    Timescale11 hours ago 0 comments

    I'm still very ill and have been in and out of hospitals. This will probably remain so for a while, while I'm tested for..... spare parts....Indeed I might need a transplant.

    The bike project has not stopped, at least not in my thoughts, but I have been doing odds and ends here and there. Mostly scrounging for parts, but I have been working on the following:

    12V system. I need to double up the converters with some dioded and the solar panel will be 12v monocrystalline. With 3 batteries that will get me a 36v ebike system.

    I have been ordering and collecting stuff for the PMF construction, but I'm going with poly epoxy instead of tightbond II. I might still use that as a costsaving measure, but the prices are not that bad. I have to do the tests because the design is starting to depend on structural EPX.

    Still after steel, but I got a lead. I also perhaps have a method to produce bushings with threats for the rear suspension.

    Until I have something to show for it, this is it.

  • Software stack

    Timescale03/30/2024 at 08:23 0 comments

    I have been really fatigued and in pain the last couple of days. On top of that, the weather did not play nice, so I was mostly desk/bed ridden. Still I managed to build some scripts and perhaps it is time to talk about what I use and why.

    The front end is a HTML(5)/javascript interface running from the main RPi on a LAMP stack. I have the option to use PHP, but the necessity has not arisen yet. I would PHP in the back-end for talking to databases.

    The main backbone of the system is Python. I wrote a socket server that talks to everything be it internal apps, the front-end or the Arduino sensor board. The reason for a socket server is twofold. It offers an entrypoint which is accessible from every level and you are not horsing around with app user sudo lists and permissions and such. Everything is run under the user who started the server.

    The code is a bit spaghetti, but for the most part it works. It works around the quirks of socket servers with a hack. Perhaps there are snippets that people find useful :

    #!/usr/bin/env python3
    import serial
    import socket
    import sys
    import os
    import glob, os
    import time
    from datetime import datetime
    
    import mimetools
    from StringIO import StringIO
    
    # Define socket host and port
    SERVER_HOST = '192.168.1.41'
    SERVER_PORT = 7654
    
    # Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    #server_socket.Server(cors_allowed_origins='*')
    server_socket.bind((SERVER_HOST, SERVER_PORT))
    server_socket.listen(1)
    print('Listening on port %s ...' % SERVER_PORT)
    # http://192.168.1.41:7654/?key:8e76@r1on&command&leftBlinkOn
    
    ser = serial.Serial('/dev/ttyAMA0', 19200, timeout=1)
    ser.reset_input_buffer()
    
    while True:    
        failureMode = False
        # Wait for client connections
        client_connection, client_address = server_socket.accept()
        # Get the client request
        request = str(client_connection.recv(1024).decode())
        #print '----'
        #print request
        reqLength = len(str(request).strip());
        #print reqLength
        #print '----'
        if reqLength > 10:
            request, he = request.split('\r\n', 1)
    
            # Get the headers
            m = mimetools.Message(StringIO(he))
    
           # Add request information
            m.dict['method'], m.dict['path'], m.dict['http-version'] = request.split()    
        #    print m['path']
            arguments = m['path'].split('?')
     #   print "args"
     #   print argCount
            argCount = len(arguments)
     #   print "args"
     #   print argCount
            if argCount > 1:
        #        print(arguments[1])
                options = arguments[1].split('&')
                if options[0] != "key:8e76@r1on":
                    failureMode = True   
        #    failureMSG = "&Err[3]=Invalid Key Error."
        
                if failureMode == False: 
                    key = options[0]
                    order = options[1]
                    command = options[2]
                    if order == "say":
                        #os.system("espeak ") + ('"') + str(command) + ('"')
                        #espeak  -v nl+f5 -s150 "dit is een test" # dutch female
                        status = os.popen('cmus-remote -Q | head -n 1 | awk \'{print $2}\'').read()
                        status = status.replace('\n', ' ').replace('\r', '')[:-1]
                        if (status == "playing"):
                            os.popen('cmus-remote -v 35%')
                        print("'" + status + "'")
                        os.system('espeak -v nl+f5 -s150 ' + ('"') + str(command) + ('"'))            
                        response = 'HTTP/1.0 200 OK'
                        response += "Content-Type: text/html; charset=utf-8\n"
                        response += "Access-Control-Allow-Origin: *\n"
                        response += '\n\n<data><say>\"' + str(command) + '\"</say></data>'
                        if (status == "playing"):
                            os.popen('cmus-remote -v 80%')
                    elif order == "audio":
                        response = 'HTTP/1.0 200 OK'
                        response += "Content-Type: text/html; charset=utf-8\n"
                        response += "Access-Control-Allow-Origin: *\n"
                        if command == "play":
                            d = 2
                        elif command == "pause":
                            d = 2
                        elif command == "stop":
                            d = 2
                        elif command == "next":
                            d = 2
                        elif command == "prev":
                            d = 2
                        elif command == "status":
                            status = os.popen('cmus-remote -Q | head -n 1 | awk \'{print $2}\'').read()
                            status = status.replace('\n', ' ').replace('\r', '')[:-1]
                            if status == "":
                                status = "Cmus not running"
    
                            duration = os.popen('cmus-remote -Q | sed -n 3,3p | awk \'{print $2}\'').read()
     duration = duration.replace(...
    Read more »

  • Bits and bobs

    Timescale03/26/2024 at 19:00 0 comments

    The multidisciplinary nature of this project is really handy for me, not only for when I am physically unable to tinker, but also because it greatly amplifies the iterative design process. As everything is connected, making choices in one spot greatly influences options in another. Sometimes this is a reason to not commit, but seeing as I have little choice, I commit more easily.

    Right now the day's are not very kind, but when I take it easy I can in fact build hardware for testing and measurements. These exercises also cause necessary change. As a test I decided to mock up a suspension arm with the stuff I had gathered. This would give me a rough estimation on how to mount them, how to attacked the shocks and what I want to use as axle buses. I also needed the practice with the welding machine and needed to find out if I could neatly cut out a half moon from a pipe for welding structural members.

    This experiment resulted in this suspension arm :

    This setup is adjustable and quite flexible. In fact I was so happy with it, this will be 1 of 8 final arms. It also does not veer off from the original design :

    The adjustability also makes it easy to play with the camber to help steering and traction. It also gives me a higher margin regarding the construction of the center piece.

    Next up was the donor bike :

    It was time to chop it up, and good thing I did! While measuring the remains of the handle bar, I stumbled on a new configuration that made a lot of sense with regards to my idea's on the seat. Seeing as I am going to have armrests, the bars van be vertical and a nice bend in the tube seems like a natural fit in that area. To be sure, I have to properly design a folding seat with armrests.

    I have the handles swapped around and the right side should get the electric motor control, but you can see that with your arms resting, this will not be a chore to control all the time. The hollow hinge is there for mock-up reasons, but in combination with the slight bend, I hope that these will fold down precisely under the seat.

    Now for the seat design which will further dictate a lot of the placement of these parts.

  • Foam is fantastic!

    Timescale03/23/2024 at 13:52 0 comments

    Update: while foam is fantastic, cheap parts not so much. The relais board crapped its pants yesterday. As far as I know everything was hooked up right. Center negative, no 12v back to the Arduino and really basic stuff. But a couple of couplers stopped working and now even some of the coils are fused? I need to rethink this 12v 5/volt situation.

    I got my 12v 8 channel relay in the mail today, so it had to make the foam case for it. While I was at it, I added a barrel plug for the coil power. Foam really is nice to work with. Cheap, easy to shape and glue, soft, light and very forgivable.

    This is what I came up with :

    Because the relay switches are relatively heavy, I added a top bar. I do not think it is needed as the whole PCB slides into its foam casing. Here you can also see the barrel plug directly soldered to the external power and ground pins with copious amounts of solder.

    I remember this trick from an earlier project involving a powered relay board. The centre positive and sleeve fit almost perfectly against the pins. This works for just about every relay board with external power because this layout of +12v - VCC - GND is the most common in my experience.

    Here is how it fits together, just like the Arduino UNO test case :

    It all fits snugly and nicely. I left the option open to add a piece of foam near the input pins in case I need some relieve for the ribbon cable. And with Velcro underneath I can place it anywhere within the console without worrying it will get loose.

  • Main Console

    Timescale03/22/2024 at 19:33 0 comments

    The last couple of days I have been focussing on the console and the power and data infrastructure. With all the feature creep of late, It has become quite necessary to have a good idea what the component placements wants to be and there is a lot of wiring going on there.

    The whole system is distributed 12V from the middle of the vehicle. This power goes to the front and back attached to bus bars. The RPi gets it's own 12v to 5 volt converter because of the power requirements while the rest will either power components directly or via the relay which is mainly used for 12v components, but it is very much possible to dedicate a couple of terminals to 5 volt. Many wire come in and out and even more stay within the console. In order no to have cable spaghetti, a good plan is needed.

     The where and the how principles remain the same here. Mounting components much to robust, light, easy to remove or move around and result in the most efficient cable routing. More then one function!

    for mounting the individual parts, i am going to make foam boxes that the components fit in snugly. Here is a test bracket for an Arduino UNO, glued and shaped to take the PCB with a tight fit :

    Here a standard UNO is fitted. Without effort, it won't pop out and the foam also acts as a shock absorber.

    The foam is cheap foam mats, cut, glued and shaped. But how to attack it to the main base of the console?

    The answer is simple, Velcro! There will be a matrix of Velcro strips on the base and each module has Velcro on the bottom. this was, fiddling around with placement is simple.

    Speaking about placement. for some reference points I also started drawing up some models based on what is connected to what and going where. Here are two examples of how the console could look:s


    Basically I placed everything around either the RPi or the Arduino Mega. It is very data centric and does not take into regard what goes out and what stays in. So the following iteration looked like this :

    As you can see, this setup is far more "hub" driven with most of the power having a clear line of side to the outside. Inside components that connect data wires are in the front.

    Now there will be exceptions to every design goal, but the main goal is to have wire routing as efficient as possible. Seeing there are a myriad of possibilities, this is a problem I'd very much like user input on. these are the components in the console:

    - 8 channel 12 volt relay board

    - 12v bus bar

    -GND 12v bus bar

    - 12v Powered USB hub (connected to RPi)

    - 12v to 5v 3A converter for RPi

    - 12v cooling fan

    - Arduino mega with GPS shield (antenna goes external)

    - breakout PCB with 5v bus bars and sensor connectors (Temp,hum,light, hall effect0

    - Rpi4 (the brains)

    - 2x 16 matrix display

    - 2 axis 1 button analogue joyPad

    - iPad mini (just needs power from hub)

    - Break out USB

    - 12v lighter socket

    - potentially a 12V main switch.

    Any suggestion is welcome, so please have at it1

  • Lofty plans

    Timescale03/19/2024 at 12:21 0 comments

    A part of iterative design is that during the designing process, elements come together and inform how one of the other much change or can be better. If you design part A and within the whole and it clashes with part B then optimisations have to be made. Sometimes this process cascades all throughout the design which can be a hassle, but ultimately results in some optimum within the general design restraints.

    One such part which has a major influence on just about everything else is the shell. Its dimensions dictate storage, freedom of movement, routing, manufacturing. On top of that, it pretty much defines the look and feel, so every few iterations of the frame and basic elements I fit a shell around it in CAD to see if everything still fits nicely within a nice shape. This informs me where I can safe space or where my tolerances are to strict.

    Now there are a lot of things one can blame on illness, alas being bad at lofting and shaping in 3D is not one of them! I know my way around 3D software and have little issues designing rigid and mechanical models, but when it comes to flowing organic modelling I really suck. Still it is the best tool for the job, and doing multiple versions gradually makes me better, but I lofting wizard I'll never be.

    I got the side view pretty much spot on, but I can not seem to get the curves and shape from the top view right. Here is my latest mock up to show what I mean :

    This all seems pretty sane as a concept. It is a handy tool to see where things can fit. Of course many spaces wasted do to the loft, but as I said, I'm no wizard at this and a ballpark model i good enough for now. The problem is the top down view.

    You can see it has quite a big bottom, but those dimensions are determined by the wheel base which is about 1 meter. This isn't a ridiculous base width for a delta trike at all, so the trunk/boot at the wheel arc level are fine. Higher up it gets a bit more bulky. I want this part to taper upwards as the rest does lengthwise. The restriction on this is the width of the solar panel, but at this moment I can't seem to make it less cube shaped. My sculpting eye does does not cooperate.

    I also was a more gentle movement towards round at the top. This would allow for the from taper to be more spacious while also looking thinner. Also can't seem to get it quite right. These are quite important dimensions as they dictate a lot about the seat/mattress system, the steering system, the door and a myriad of other elements.

    Perhaps you are thinking that this does not look all that fat, but realize this is the halfway cutaway. The full shell does not look fair at all. The seat is to big in places, the footwell seems a bit tight and there is little room for reinforcements for the door mechanism for example. There is ample space for storage though. I can bring a library, full camping gear and then some... Perhaps also not a key goal.

    Well, that is where we are right now. A semi decent fitting structural body. I'll just have to keep hack and slicing away at it until it reaches maturity. I Think I'll do some detailed design work of the seat and steering mechanisms as these are also closely intertwined. Work a but more on the drivetrain and then seen where the splines land!

  • Intergration, software and automation.

    Timescale03/17/2024 at 22:40 0 comments

    While you might argue that this is all unnecessary weight and a drain on the battery, it me reply that this is the core essence of the idea that every part should at least have 2 functions. In this case some have many many more.

    Lets look at the current integration of the hardware stack. I try to let each element do what it does best

    The core is the raspberry pi. It runs a LAMP stack for the interfaces on the IOS devices. It also runs a Python web service which communicates with the Arduino. It sends commands and data requests and gets back the status and requested data in XML format in return. The reason why this is a separate web server is so other platforms and devices are not depended directly for the interface software to manage data streams. If a device needs GPS data, it can ask for it without waiting for an update on the core system or relying on a Rube-Goldberg machine'esque communication chain where some some PHP script must output suitable data for the end device by calling the Python script next door every single time. Now it does not matter if I need the data in the shell, in PHP, in Python itself or in javascript running on the consoles.A third socket service will eventually run on the RPi for the rear camera so it can run on any screen when needed.

    The RPi also runs the music via CMUS and can do voice alerts with espeak. These are combined in software to not interfere to much. I also want to add FM and DAB+ radio and I know it can be done, but more study is needed for that.

    The arduino could not be simpler. It just has IO and follows commands via serial and sends data on request back via serial. Want to let the indicator blink left? Press the left indicator icon on the control screen which will send a httprequest with the proper command with JS to the python server which will send it to the Arduino which, if all goes well, starts the blink function and makes the relay switch go on and off. It sends back XML data about the recieved command, the result and so on.

    Then there is the 2 by 16 matrix display. I wanted the dash to be as clear as possible. a main screen, a start key switch and some USB ports, but who does not like a matrix display? I mainly use it for debugging right now to see is the arduino is doing what it should directly, but It could be fun for it to display random semi relevant data. I think I'll keep it.

    Of course there are a gazillion ways to do this, but this is what I cobbled together and it sees quite stable.

  • Interfaces

    Timescale03/17/2024 at 22:07 0 comments

    For the last couple of days/weeks I have had some health setbacks. I'm working on it, but it is slow and tedious. So I am very limited to what I can do on the project. I can not fabricate test parts, so various aspects of the design have been slowed down. I can not carry heavy loads or ride very far, so the materials I need I can not always pick up.

    What I can do how ever is assemble some hardware and write some software and that is precisely what I have been doing (and now writing this blog of course).

    My Raspberry dev station is now fully committed to this project. I have a dedicated OS image running and can install packages and write stuff to my hearts content. The basic controller system also is pretty far software wise, however it is now based on an UNO and not a MEGA and while I think I do not need to much IO, I do need more hardware serial, because software serial for the GPS is bogging the main loop down noticeably.

    To the raspberry I have attached the GPS module, a 4 switch relay, a DHT11 sensor, a light sensor, a matrix screen form monitoring via I2C, an analogue joypad (which is no longer needed... here), a test button for ezButton library( probably also not needed) and a potentiometer which will be part of the steering system for auto direction off functionality because... Why not?

    I ordered a cheap second hand iPad mini for the main console and dusted off the iPhone I had laying around. Now my life looks like this :

    The main screen and the quick controls.

    A mess of wires. Nothing to complecated.

    Next log will be about the specifics of the automation and communication.

  • Release the geek....

    Timescale03/17/2024 at 21:34 0 comments

    Seeing how the battery and inverter are heavy, why not give them more function apart from feeding the drive train..... is the excuse I use to let loose feature creep and throw everything but the kitchen sink at this projects (although adding a sink to a tiny kitchennette to it).

    What could I go with that power.... Here are the features I plan to implement in the order from sensible to silly:

    - Main front and read lights.
    - Indicator lights.
    - A Horn.
    - Internal lighting.
    - Internal charging points.
    - Fans.
    - A rear facing camera.
    - Proximity sensors.
    - Odo meter.
    - Music and or a radio.
    - GPS and navigation.
    - WIFI.
    - Internal and external temp and humidity sensors.
    - Alarm system.
    ... This list will not remain static.

    So basically I'm talking adding computers. This is a part of the project I can work on most days even if I have trouble walking or lifting. What I ended up with and what I am testing now is the core system and writing the software for it.

    - The main computer will be a Raspberry Pi 4 4GB.
    - The controller will be an Arduino mega with a GPS shield and various sensors and relays attached. The Arduino will communicate with the RPi over serial for sending commands and receiving data and status
    - As a main console I'll use a iPad mini with a webapplication that runs off of the RPi
    - For the quick control panel an old iPhone 6 is used with its own webapp.
    - Powered USB hubs go into the console, in the battery compartment and in the back storage compartment.
    - The system, apart from the e-bike stuff which will be 24v, 36v or 48v, most power will be distributed as 12v. At certain location like the console it can ben boosted down to 3.3v and 5v.
    - Of course there must be a PV panel on the roof with at least 100 WH, but preferably 140.

    The only system I contemplated but are probably not going to add is regenerative breaking. It would add cost and complexity to the drive train and that part is difficult enough as it stands..

  • Weight

    Timescale03/17/2024 at 21:10 0 comments

    While available materials is a large restriction, in essence the real restriction is weight. This thing must be as light weight as I can make it within the feature list. This of course greatly effects the types of material and techniques and the way to implement them.

    Of course a long steel frame will not weight nothing. Neither will a battery, a motor or for that matter "me"! but even here gains are to be had.

    For example, while the frame will be the heaviest part most likely, it will not be as heavy as the combined weight of a bicycle frame AND a camper frame. These can share structural parts between them. It also means with will be a lot shorten than the combination of a bike and trailer.

    Another principle is that, where possible, an element should have at least 2 functions. If it is structural for the frame, there is no reason for it to be part of the seating system, wiring infrastructure or support for mechanical systems like the tank steering system (yes... going to do that). The seat of course transforms into a mattress and the hull is both protection, mounting area, surface for system integration like electrical, aerodynamics and making it look cool.

    So the hull has many functions, but also, like our skin is the biggest organ, this is the biggest part, but it can not weigh a ton. After a lot of research, I decided that I'd make the bulk of the hull out of laminated XPS foam. People build boats out of it, so this should be doable and it is cheap. I still have to do the gluing, shaping and laminating experiments, but the core concept seems sound. Where needed sturdier re-enforcements will be added, but the whole shell should not weight more than 10 to 15 Kilograms and that is probably a high estimate. that stuff is really light!. (and even if re-enforcements are needed, I'll try to make those double as cable routes.

    The seat matrass system will be wood foam and fabric and the center console and cooler will also be XPS.