Close
0%
0%

Tiny Bit Machine

A solar powered handheld doodad to explore the binary.

Similar projects worth following
Solar powered, battery free hardware to run an interpreter on the attiny85.

Charge time in full sun: 3-6 minutes.
Run Time: 30-45 minutes.

Hardware to run (TGRK), a tiny handheld interpreter for the attiny85.

Program is stored in a 127 byte int8_t array.

Negative numbers (-128,-1) are keywords, positive numbers (0-127) are integers.

The device runs off a 1.5F, 5.5v supercapacitor which is charged by a small solar cell. To prevent the supercapacitor from exceeding its maximum of 5.5v, I have placed a 5.6v Zener diode to limit the voltage before the blocking diode and supercapacitor.

In direct sunlight it only charges up to ~5.2v, which is fine in my opinion. It can take 3-6 minutes to charge from 0v to 5.2v.

The device runs for about 30-45 minutes after a full charge. 

The attiny85 at 1mhz with BOD off, seems to run fine all the way down to 1.6v... but at this point the LEDs are barely visible. If the voltage goes below 2 volts, the device will go into deep sleep. When this happens the user will need to recharge it to keep working.

User input is 5 buttons on a resistor ladder on ADC2 of attiny85. Depending on what menu the user is in, they will do different things. With the exception the < and > buttons will always either be navigating menu, byte, or bit position.

  • Left Button       <
  • Right Button     >
  • Toggle Button  T
  • Save Button     S
  • Run Button       R

The devices output are two red LEDs. I chose red due to low forward voltage, and it is easier on the eyes if using the device in low light.

If the current selected bit in the current program byte is a 0, then LED 0 is lit, if its a 1, LED 1 is lit.

prog.grk

Program file for transferring over Serial

grk - 749.00 bytes - 09/07/2024 at 08:08

Download

tgrk.py

Python Serial Transfer tool

x-python - 4.60 kB - 09/07/2024 at 08:08

Download

TBM_TGRK.ino

Arduino Sketch

ino - 28.17 kB - 08/30/2024 at 15:27

Download

TGRK_KEYWORDS.pdf

Keywords Table

Adobe Portable Document Format - 77.25 kB - 08/30/2024 at 15:27

Preview

  • 1 × ATTINY85 Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers
  • 1 × 60x40 Proto Board For attaching components
  • 1 × Tic Tac Box Case
  • 1 × 8 Pin IC Socket
  • 1 × 53x30 5v Solar Cell

View all 14 components

  • Game code

    g0730n2 days ago 0 comments

    Here is the complete game code in TGRK. It ended up being 294 bytes, so I cannot test it on the device. My options for running this game are either A. expand the program size from 127 to 300 bytes, which would make me have to refactor a lot of different things. or B, implement the game in C and have it as a feature on the device. 

    Probably going to keep the interpreter as it is and add the game as an extra feature. Either way, it was fun writing this program in TGRK:

    EDIT: I Slimmed it way down. Removed the menu system and just have < > and T buttons. The math for damage and monster health calculations had to be slightly slimmed down as well. As well as removing the option to roll to run away. Now during a fight you can just run.

    I also removed XP, and changed gold (Stored in R3) as the players damage multiplier. HP is also a damage multiplier.

    Simplified Code now fits in exactly 127 Bytes. Will get my serial dongle out tomorrow and drop it on there and see if it works!

    * FIGHT *
    F7
      FUNC
        CG RND 64 AND CE R8 3 AND CG R1 R7
          R5 R1 DIV 2
          R8 1
          SEP
        CE R8 1
          R6 RND ADD R1 ADD R5 DIV 12
          R2 SUB R6
          R8 0
          SEP
        CE R8 2
          R6 R2 ADD R3 ADD RND DIV 12
          R5 SUB R6
          R8 1
          SEP
        CLE R5 0
          R7 R1
          R3 ADD RND DIV 2
          R8 0
      FUNC
    
    * CONTROLS *
    F8
      FUNC
        BG
        L0L
        L1L
        S1
        CE BV 1
          R1 SUB 1
          L0H
          SEP
        CE BV 2
          R1 ADD 1
          R8 3
          L1H
          SEP
        CE BV 3
          L1H
          L0H
          R8 2
          SEP
        CE BV 3 AND CE R1 0
          R2 ADD R3
          R3 0
          BB R3
          SEP
        F7
      FUNC
    
    R2 64
    
    * MAIN LOOP *
    CG R2 0 AND CLE R1 126
      F8
      LP
    
    EOP

    Original Code:

    R2 64
    
    * INN *
    F1
      FUNC
        CE R8 0 AND CG R2 0
          R2 ADD R3
          R3 0
          SEP
        CE R8 1
          BB R3
          SEP
        CE R8 2
          BB R2
          SEP
        CE R8 3
          R1 ADD 1
          SEP
      FUNC
    
    * MONSTER ATTACK *
    F2
      FUNC
        R6 RND ADD R1 ADD R5 DIV 12
        R2 SUB R6
      FUNC
    
    * PLAYER ATTACK *
    F3
      FUNC
        R6 R2 ADD R4 ADD RND DIV 12 ADD 1
        R5 SUB R6
        CLE R5 0
          R7 R1
          R4 ADD R1 DIV 10
          R3 ADD RND ADD R1 DIV 2 ADD 1
      FUNC
    
    * FIGHT MENU *
    F4
      FUNC
        CE R8 3
          F2
          SEP
        R8 3
        BG
        CE BV 1 AND CG RND 60
          R1 SUB 1
          R5 0
          R8 0
          SEP
        CE BV 2 AND CG RND 50
          R1 ADD 1
          R5 0
          R8 3
          SEP
        CE BV 3
          F3
          SEP
        CE BV 4
          BB R2
          R8 2
          SEP
        CG R5 0 AND CG R2 0
          LPF
          SEP
        R8 3
      FUNC
    
    * ROAD MENU *
    F5
      FUNC
        CE R8 3
          R1 ADD 1
          SEP
        CE R8 0
          R1 SUB 1
          SEP
        CE R8 1
          BB R1
          SEP
        CE R8 2
          BB R2
          SEP
        CG RND 50 AND CG R1 R7
          R5 R1 DIV 2 ADD 1
          F4
      FUNC
    
    * MENU LED *
    F6
      FUNC
        CE R8 0
          L0L
          L1L
          SEP
        CE R8 1
          L0H
          L1L
          SEP
        CE R8 2
          L0L
          L1H
          SEP
        CE R8 3
          L0H
          L0H
      FUNC
    
    * BUTTON INPUT *
    F7
      FUNC
        BG
        CE BV 1 AND CG F8 0
          F8 SUB 1
          F6
          SEP
        CE BV 2 AND CL F8 3
          F8 ADD 1
          F6
          SEP
        CE BV 3 AND CE F1 0
          F6
          F1
          SEP
        CE BV 3 AND CG F1 0
          F6
          F5
      FUNC
    
    * GAME LOOP *
    F8
      FUNC
        CG R2 0 AND CLE R1 126
          F7
          LP
          SEP
        CE R1 127
          L1L L0H S1
          L0L L1H S1
          LP
          SEP
        L1H L0H S1
        L1L L0L S1
        LP
      FUNC
    
    EOP

  • RNG

    g0730n2 days ago 0 comments

    To generate psuedo random numbers for use it the game, I found a method that seems like it will work great for the randomness I need.

    Every time a button is pressed, we get the LSB of current millis() timestamp.

    Our variable "int8_t random_number" is our global variable for storing the current random number.

    First we shift bits 1 position left.

    Then XOR the LSB

    Then apply the variable to bitmask 127, which will guarantee the MSB is never a 1. We don't want any negative numbers stored in this variable.

    Considering a button will be pressed every time any action is done in game, the generator will generate a new number every time a button is pressed, then we can read that number for applying to our game code.

  • Game Update, etc.

    g0730n2 days ago 0 comments

    Power Consumption Deepsleep

    First off, I have been running this program on device past two days:

    BB PAXX D0 LP

     It blinks the binary value if the adc reading, which ranges from 20-53 (2.0v-5.3v). Then goes into low power mode until next button interrupt.

    Pressing it periodically throught the day and checking voltage, while making sure solar panel was covered, it ran for about 36 hours before hitting 2v and going into power down mode.

    Another use case for this could be adding a RTC and using it as a clock... hmmm.

    Now onto my current thoughts about the game for device.

    Game Ideas:

    I wrote a mockup of the game I want to run on device in python. If i need to quickly write and test a program, often I will use python before porting it to C, etc. This allows me to know how many variables, functions, etc I need and get an idea of what the programs structure will look like.

    I believe some VERY simple game could be written in TGRK, but the game I want to add would exceed 127 keywords. At this point I am thinking adding it as a built in feature of the arduino sketch. I believe there is enough flash left to add it in there.

    The game itself is a 1 dimensional RPG. The world map is a path with 127 "rooms" or maps. Map 0 is the INN, where the player can pay to sleep and restore health.

    On any map cell 1-126 there is a random chance for a monster to appear. Their health and damage dealt to player increases in a somewhat random manner the higher the map level. Every time the player kills a monster 3 things happen:

    1. Monster drops random amount of gold based on map difficulty (more at higher levels)
    2. Player gains XP
    3. The map EXPLORED variable gets set to current map cell. Monsters don't spawn on map equal or less than the EXPLORED value. This makes it so map cells are cleared after a monster has been killed on one. And also for "fast travel" to and from inn.

    Fast travel. When player leaves inn and moves forward into world map, game will quickly blink through each empty map cell until reaching unexplored one. Same with traveling back to inn.

    This becomes incredibly helpful when at higher levels as no not have to manually click through 100+ map levels just to heal up. Playing on the Python version I noticed several things. 

    At higher levels 80+ I would have to travel back to the INN more and more frequently, as monsters become stronger and stronger. 

    So far I have only made it past lvl 90. I am still tweaking the balance for the games calculations. I want it to be difficult but not impossible.

    When players HP gets to 0, player loses, game is over.

    If player reaches map 127, player wins, Game over!

  • A Game in TGRK?

    g0730n3 days ago 0 comments

    For the final addition for this device for the Tiny Games Contest, my challenge is to write some sort of game that runs on the Tiny Bit Machine. And write it in TGRK, AND write it into the device one bit at a time.

    I will definitively develope and test using the serial transfer I added, but once the program is complete I will punch it in one bit and byte at a time. The serial transfer program is working flawlessly now. I did some more work on it yesterday and have tested transferring more than 60 bytes and havent had an error yet.

    Limitations:

    The 127 byte progam length is a real limitation for any complex game. It has to be simple. Just having all 8 empty functions initialized and setting all 8 registers once uses about 55 bytes.

    I need to modify how I set up detecting button presses within TGRK. The way it works right now is we call a button, e.g Left button: "BL" and when TGRK reads that keyword, it waits until that button is pressed before continuing program. I need to do something more like this:

    BG
    BV

    Button Get: "BG" will wait until any button is pressed, and when one is, it will store the button code (0-4) in the Button Value: "BV" register. Thr BV register can then be read to see what the button press was.

    About a year ago, I wrote an RPG game in BASIC on the Smart Response XE running Arduino Basic. The entire game ended up being about 6Kb, which was maxing out useable memory.

    I will probably use some of the concepts i used in that game, but obviously i need to optimize and slim it down.

    In that game I used Arduino Basics "RND" Function quite heavily which generated a random float between 0.001 and .999.

    In this TGRK game I will also need a random number generator, which I will probably name this keyword RND as well. But it will generate a number between 0 and 127. I have seen posts somewhere about using a timer to generate a random number on Attiny85, I may do that or when the BG function is waiting for input, have a counter constantly counting from 0-127, whatever it is at when button is pressed, that is the random number for that turn.

    In a RPG generating random numbers is essential to almost everything. In each following step we roll a number: Will a monster appear this turn? Can I run from it? If it attacks, how much damage does it do? How much damage will I do this hit? Will it drop a coin?

    We will see!

  • More Serial

    g0730n4 days ago 0 comments

    Here are some screenshots of serial transfer python program, as well as my code highlighting style for TGRK in notepad++. Stayed up a little too late last night working on this.

    Discovered there are some issues with transferring more than 30+ byte program. I have yet to check if it's just the Attiny85 not sending everything back, or if it's not receiving it all. Under 30 bytes, it seems to work every time.

    To transfer, I plug in serial adapter to Devices PB0 and PB1

    PB0/MOSI = TX

    PB1/MISO  = RX

    1. Go to run menu on device:
    2. MENU 0 > Selection 2
    3. Then start python script.
    4. Then press run button on device, and transfer runs.

    The python transfer script has a dict with all keywords, and reads a file in same directory called "prog.grk". This makes writing a program for device as easy as connecting to PC through serial adapter, editing program file, and running python script.

    When it reads through the file, it skips any whitespace and adds the corresponding integer to a list, which then gets converted to a byte array to be sent to Attiny85. This allows us to write TGRK code using spaces, tabs, etc. At least one whitespace between each keyword or integer is necessary, but as many one wants to use is permissible. The EOP keyword is required at end of program when programming this way. Here is an example:

    This code just reads the floating PB2 ADC pin and lights led 1 or led 0 depending on it's value.

  • Serial Program Transfer

    g0730n5 days ago 0 comments

    There was enough flash and RAM available after finishing interpreter I decided to go ahead and impliment the ability to transfer programs to device using Serial. 

    I suppose this takes away from the antiquated method of punching in bits manually, but for testing purposes it is great!

    Using a py script with pyserial on PC side, and usb-uart adapter, it works! Kinda some buggy stuff had to sort through with transfering negative integers though. Will have to fiddle with it more to understand the serial protocol more.

    I was also thinking about how I submitted this device to the Tiny Games Contest, but its not "exactly" a game unless you consider programming in an incredibly tedious way a game. It is definitively an educational device, and you could write some sort of game that runs on the device.

    I suppose that will be my final hurrah before the contest ends, is write up some sort of game that runs on this device.

    Toodleloo!

  • Ordered PCB's

    g0730n6 days ago 0 comments

    I have ordered 5 PCB's which is the smallest order JLCPCB will allow. If these all check out and I didn't make any mistakes, I will post the Gerber file here. Having a PCB for this project will make assembly fast and easy.

    I added a footprint for the other style of 5.5v Super capacitor on top the existing super capacitor footprint so both styles of button capacitors can be used.

    Used a white PCB to reduce heat absorption from sun while charging.

    FRONT:

    BACK:

    I have gotten several messages on here for PCBWAY sponsorship, but I have been using EASYEDA, and JLCPCB for years (unsponsored), and am happy with their designer and service. I also like the easy access to ordering components from LCSC. So I don't plan on switching anytime soon. Sorry PCBWAY!

  • Documentation

    g0730n7 days ago 0 comments

    The build instructions are complete, and I am in the process of writing up the guide for programming on the device using TGRK.

    I am thinking of making a video where I build one on a breadboard.

    This has been a very fun project to work on. I have learned a bit more of C programming and working with the Attiny in the process and glad I can share the journey with anyone who is interested on here.

  • New Run Time Record

    g0730n08/31/2024 at 16:41 0 comments

    After posting the video from last log, I turned the device off and did not touch it until this morning. I loaded the blink program from eeprom that I demonstrated writing in the video posted in the last log. Running this program, the device ran for 55 min before < 2v power off.

    Placing the device in the sun after it went into deepsleep, it powered back on amd resumed the blink program once voltage got over 2v. When the device goes into deepsleep because of low voltage, it deepsleeps and checks voltage every 2 min. This device could easily charge from 2 to 5v in 2 minutes.

    I have begun adding build instructions as well as a more detailed components list.

  • Video of Device Working

    g0730n08/30/2024 at 18:25 0 comments

    I didn't intend for the video to be 15 min long, but thats how it ended up.

View all 32 project logs

  • 1
    Components I Used

    Below are links to the components I used, or equivalent parts. (Amazon links are through my amazon associates account and are only components I have tried and tested). 

  • 2
    Assembly

    I would strongly recommend building the device on a breadboard first and flashing/testing the code before soldering together. Here is the schematic:

    ADC values in code for buttons, as well as VCC voltage may vary depending on values/tolerances of resistors you use. 

    In this prototype I used different value resistors than what is posted on schematic.

    The Button resistors are pretty close to what I used, but I don't remember the exact values used, so in the Arduino sketch you will most likely have to adjust these values.

    The VCC voltage divider has been changed in schematic to save power.

    The working prototype is using a 100k to VCC, and 22k to GND for VCC adc voltage divider. In the schematic I changed that to 3.9M and 1M, with a 100nf capacitor.

    If you use the 100/22k, the code should work "out of the box" for this, as well I know it works. 

    I am going to test the higher level resistors and post on whether or not it works reliably, so until then probably just safer to use 100/22k.

    Using the provided schematic, here is the order I did everything:

    1. First make sure the Super Capacitor is at 0v, if its not then drain it with a resistor. Place and solder it on the protoboard.
    2. Place and solder buttons
    3. Place and solder IC socket
    4. Place and solder pin header and slide switch
    5. Place and solder LEDs
    6. Now begin placing and soldering resistors, diodes, and capacitors.
    7. Once all those connections are made, use jumper wires to finish off connections.
    8. Finally, on the back side, use two short jumper wires to attach solar cell, making sure to have the polarity correct. I attached one end, then used some 3mm double stick foam tape to preven the solar cell from moving or shorting anything out on back, then once it was placed soldered the other end.

    A PCB made for this project is in the works, this will make building the device 10x easier. Attaching many jumper wires in a small space is a headache.

  • 3
    Flashing Attiny85

    I used Arduino Uno as ISP to flash device.

    1. Download ino file from this project page files or my github.
    2. Install Tinycore for attiny85: https://github.com/SpenceKonde/ATTinyCore
    3. "Burn Bootloader"
    4.  using ISCP to attiny85:
      1. Board: ATTinyCore: Attiny25/45/85(No Bootloader)
        1. BOD: Disabled
        2. Chip: Attiny85
        3. Clock Source: 1mhz Internal
        4. Save EEPROM: retained
        5. LTO: Enabled
        6. millis()/micros: Enabled
        7. Timer 1 Clock: CPU frequency
    5. Flash Attiny85 using "Upload Using Programmer".

    If the ADC values for buttons are correct, you should be able to navigate menu. I think i used a multimeter to get the exact voltage ratios for each button press.

    If some buttons aren't working, you will have to adjust in sketch and reflash.

View all 5 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates