Still using AsteroidOS and loving it!

image

A while back I switched my LG Watch Urbane (bass) from Android Wear to AsteroidOS. My initial reaction was really positive, but I wanted to come back to post later on how the long term use was going. Truth is, it’s great!

image

Don’t get me wrong, Android Wear had some nice features, a few of which I still miss. Most notably the one where the motion of turning your watch towards your face caused the screen to turn on.

image

But other than that, AsteroidOS has met every need I have in a smart watch. Most notably that of telling time and the synchronized phone notification. Of course the weather and calendar apps are handy too. When it really comes down to it, I realized that I didn’t use Androids thousands of apps on my watch because the screen is too small. Why would anyone watch an HD movie on a 1.5″ screen?

AsteroidOS has really been great at having useful apps that one would actually want to use on the small screen, which just makes sense. I’ve also gone weeks or more without rebooting the watch. The firmware is really robust and never seems to have an issue.

The best part of all? The battery life is phenomenal! Since switching, I went from about 9 or 10 hours with Android Wear to 2 days with AsteroidOS. And that’s a win win for me!

Linux – keep it simple.

Fixing a Galaxy Note 9 with broken glass

image
Well, at least attempting to. Unfortunately it didn’t end very well. A friend of mine broke the glass screen of their Samsung Galaxy Note 9. They have a warranty on it, but they already broke the screen once, and now they would have to pay several hundred dollars to have this one fixed again.

Remember: Glass screen protectors are your friend! A case doesn’t protect the screen! Always buy a glass screen protector!

They bought a replacement glass kit for around $30 and hoped to do the work themselves and save a lot of money. Once they started watching how to videos, though, they realized that they were in over their heads. So, they came to me…..

Of course, my first suggestion was that they seek a professional. Turns out the only professional in our town wanted $300 to do the work. Unfortunately for my friend, that was still too much. So, they asked me to give it a try first.

I told them this wouldn’t work. I don’t have the right equipment. I don’t have a warranty. I could ruin the screen. But, they were persistent, so I gave it a go.

The key is to get the glass hot, but not hot enough to melt the screen. So I used a heat gun and a thermometer to adjust it to 90 degrees Celsius. Once that was set I started heating the glass.

Then, using a toothbrush, I started applying isopropyl alcohol to the shattered portion of the screen. This breaks down the glue. As carefully as I could I used plastic screwdriver type tools to lift off the broken chunks of glass.

All was going really well for the first 30 minutes. I had lifted off the glass in about the shape and size of a quarter, and was moving right along. And then… while lifting a longer piece of glass, it levered against the screen, and poked the digitizer, causing a huge green line and purple line right down the middle of the display!
image
I was really bummed! Now the screen and the glass were ruined, and, despite the warnings I gave my friend beforehand, I’m pretty sure that they lost all confidence in my phone skills. They ended up turning it in for repair.

So, the moral of the story is: buy a good glass screen protector, and don’t try to fix broken glass without the right tools.

Linux – keep it simple.

Colido 3D DIY Slic3r Settings

IMG_20190720_091201

As promissed, I wanted to make a post with my slicer settings that I use for my Colido 3D DIY printer in Slic3r. Why? Because I’m learning that slicer settings matter, big time. If the above picture loaded for you, then you can see that the same 3D model will drastically change when sliced with different slice settings. Warping, crummy prints will plague you if you don’t get this right.

I learned this the hard way, and, after dozens of test prints, I finally found something that prints decent for my modest printer. If any of you happen to have a Colido 3D DIY printer, then maybe this can save you dozens of prints spanning days or weeks of free time. At least, that’s the goal.

Here is my colido3Ddiy.ini file:

# generated by Slic3r 1.2.4 on Wed Jul 17 17:27:12 2019
avoid_crossing_perimeters = 0
bed_shape = 0x0,200×0,200×200,0x200
bed_temperature = 0
bottom_solid_layers = 3
bridge_acceleration = 0
bridge_fan_speed = 100
bridge_flow_ratio = 1
bridge_speed = 60
brim_width = 0
complete_objects = 0
cooling = 1
default_acceleration = 0
disable_fan_first_layers = 1
dont_support_bridges = 1
duplicate_distance = 6
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; set bed target temp\nG28 X0 ; home X axis\nM84 ; disable motors\nG1 Z169 F200;
external_fill_pattern = rectilinear
external_perimeter_extrusion_width = 0.35
external_perimeter_speed = 70%
external_perimeters_first = 0
extra_perimeters = 1
extruder_clearance_height = 20
extruder_clearance_radius = 20
extruder_offset = 0x0
extrusion_axis = E
extrusion_multiplier = 1
extrusion_width = 0.35
fan_always_on = 0
fan_below_layer_time = 60
filament_diameter = 1.75
fill_angle = 45
fill_density = 30%
fill_pattern = line
first_layer_acceleration = 0
first_layer_bed_temperature = 0
first_layer_extrusion_width = 200%
first_layer_height = 0.32
first_layer_speed = 70%
first_layer_temperature = 195
gap_fill_speed = 20
gcode_arcs = 0
gcode_comments = 0
gcode_flavor = reprap
infill_acceleration = 0
infill_every_layers = 1
infill_extruder = 1
infill_extrusion_width = 0.29
infill_first = 0
infill_only_where_needed = 0
infill_speed = 20
interface_shells = 0
layer_gcode =
layer_height = 0.16
max_fan_speed = 100
min_fan_speed = 35
min_print_speed = 10
min_skirt_length = 0
notes =
nozzle_diameter = 0.4
octoprint_apikey =
octoprint_host =
only_retract_when_crossing_perimeters = 1
ooze_prevention = 0
output_filename_format = [input_filename_base].gcode
overhangs = 1
perimeter_acceleration = 0
perimeter_extruder = 1
perimeter_extrusion_width = 0.21
perimeter_speed = 20
perimeters = 3
post_process =
pressure_advance = 0
raft_layers = 0
resolution = 0
retract_before_travel = 2
retract_layer_change = 1
retract_length = 3
retract_length_toolchange = 10
retract_lift = 0
retract_restart_extra = -0.01
retract_restart_extra_toolchange = 0.5
retract_speed = 40
seam_position = nearest
skirt_distance = 6
skirt_height = 1
skirts = 1
slowdown_below_layer_time = 30
small_perimeter_speed = 30
solid_infill_below_area = 70
solid_infill_every_layers = 100
solid_infill_extruder = 1
solid_infill_extrusion_width = 0.59
solid_infill_speed = 60
spiral_vase = 0
standby_temperature_delta = -5
start_gcode = M104 S195 ; set temperature\nG28 ; home all axes\nG1 Z5 F200 ; lift nozzle\nM109 S195 ; wait for temperature to be reached
support_material = 1
support_material_angle = 0
support_material_enforce_layers = 0
support_material_extruder = 1
support_material_extrusion_width = 0
support_material_interface_extruder = 1
support_material_interface_layers = 3
support_material_interface_spacing = 0
support_material_interface_speed = 100%
support_material_pattern = pillars
support_material_spacing = 2.5
support_material_speed = 60
support_material_threshold = 0
temperature = 195
thin_walls = 1
threads = 2
toolchange_gcode =
top_infill_extrusion_width = 0.2
top_solid_infill_speed = 50
top_solid_layers = 3
travel_speed = 130
use_firmware_retraction = 0
use_relative_e_distances = 0
vibration_limit = 0
wipe = 0
xy_size_compensation = 0
use_volumetric_e = 0
z_offset = 0
before_layer_gcode =

So in these 125 settings are the keys to a successful print on my 3D printer. I’d like to point out just a few things about them though:

  • perimeter_speed = 20 ; Going slow on the perimeters really helped define the shape of my prints. It does make it take much longer, since I’ve slowed down all the speeds, but it does make a huge difference on the quality of the finished product.
  • layer_height = 0.16 ; Having a finer layer height also drastically improved the print quality.
  • infill_speed = 20 ; You could probably make this faster by raising the infill speed, but with my cheap printer, the slower the better. However, most of my prints take hours longer at this speed.
  • perimeters = 3 ; Having thicker walls for the edges of things made my prints significantly stronger without having to up the fill density, which I usually keep at 30-40%.

It’s a bit tedious if you are playing with a new to you printer and don’t know where to start. Having 125 settings to work with really makes it a daunting task, considering the best thing to do is to change one setting at a time. Hopefully these settings will help point someone else in the right direction, or at the very least, help another Colido 3D DIY owner.

Linux – keep it simple.

LTE Project renamed “Bone Phone”!

Well, today is my last post on the LTE project. After showing it to my co-workers, it has now been renamed the “bone phone” because of it’s unique shape and color! I’ve also included the README.md at the end of this post with the full story.

To God be the glory, I learned a lot, and made a lot of functions with this phone. The main points are:

  • Send Text messages to any valid number
  • Receive and read text (SMS only) messages from anyone
  • Reply or delete text messages
  • Turn LTE on/off
  • Turn GPS on/off
  • Get your current location
  • Send your current location to someone else via text
  • Compass heading (must be moving to be accurate, based on GPS)
  • Status Bar with battery, GPS, cellular, and messages stats
  • Current local time

There was a lot more things that I wanted to do with this project. unfortunately, I ran out of memory:

Sketch uses 26938 bytes (83%) of program storage space. Maximum is 32256 bytes.
Global variables use 1567 bytes (76%) of dynamic memory, leaving 481 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

As you can see from the warning, I’m running out of dynamic memory, or ram. I’ve tried adding a few more things, but anything I add tips it over the edge. Even just a few bytes added seems to make the device slow down so much that it is unusable. You are supposed to leave 512 bytes for running the program, and I’m only leaving 481, which slows it down a bit. But, be sure to check out the project on my GitLab for all the files, the pictures, videos, and 3d printer cad drawings and program! It’s all up for you to work on and improve!

Thanks for following along with me on this project! It’s been a really great learning experience! Not only that, but to God be the glory, it even works! You can read more about it in the readme if you’d like. This readme also includes operating instructions. (It’s easier to read by following the link to the mark down document, but I’ll post it here in case you need it.)

# LTE project (nickname: “Bone Phone”)

You can read more about this project on my blog: https://thealaskalinuxuser.wordpress.com
Just search for “LTE project” to see how you can build this open source hardware texting phone for yourself!

This phone can send and receive text messages. Runs off of a 9 volt battery, and has six buttons.

# Operating instructions:

1. Turn on the Bone Phone by flipping the power switch to the “on” position.
2. Once it boots up, you will be presented with the main screen. On every screen, use the numbered button that corosponds to the menu item to select it.
3. Any screen that has you input text or numbers, use the buttons to navigate, 1 is up, to scroll through the numbers or letters, 2 is down, to scroll through the numbers and letters. Whatever letter or number you select is not saved to that spot until you use button 3 (left) or button 4 (right), at which point the letter/number is saved/entered.
4. Some screens tell you to push the select button (button 5) to do special functions. If needed, the screen will display the action you should take.
5. At any time, you can press the “home” button (button 6), which will take you back to the main menu.

# Features

– Send/receive text messages
– Turn on/off data or gps
– View GPS location and send as text
– Compass heading screen if GPS is on
– View network info.
– Using serial over USB, you can do many more features such as download web pages, upload to the web, and more.

# Notes

– I tested this with StraightTalk and Hollogram.io simcards. Both worked, but only the hollogram card would allow data if using the serial over USB connection. Both worked for texting.
– When sending a text to a number, you need either of these two formats: +19078675309 or 19078675309. Some phones will not accept unless you have the “+” sign in front of the number. So far, all phones accept the text when you use the “+” sign.
– The device has 2 batteries. One 9 volt battery, which is disposable, and non-chargable. The second battery is a 3.7 volt battery for the modem, which is charged by power from either board input or the 9 volt battery. The power battery percentage from the phone on the status bar is actually for the modem battery, and doesn’t tell you how much battery power you have left in the 9 volt battery, unfortunately.
– The serial over USB works, and you can talk to the board that way, sending and receiving texts, etc.
– The included truth table outlines the different screens and button combinations.
– The bone phone was also supposed to have a mini browser/ftp/http get/put method, as well as a game, but I ran out of memory on the device. Come on, I only had 32 kb of space and 2 kb of ram to work with!

# About – Or, Why “bone phone”?

Well, the design is somewhat dog bone treat shaped, to protect the buttons. Add to that the fact that the original that I 3d printed was white, it did look like a big bone. While showing it to my co-workers one day, one of them said it’s a bone. One then said it was a bone phone. They then all started laughing and we nicknamed it the bone phone.

I built this phone so I can learn about cell phones, c and c++ programming, and work with open source open hardware on a project. This bone phone met all those goals. This bone phone cannot make phone calls, but can send or receive texts.

# Hardware Components

The main board is an Arduino Uno (or knock off), and a Botletics LTE shield, both of which are open source hardware. There is also a Nokia 5110 screen, a slider (on/off) dpst switch, and 6 momentary switches, made by QTEATAK. There were also 6 550 ohm resistors, and a 3.7v lithium cell phone battery that I took out of an old HTC sense cell phone, but any 3.7volt LiPo/Li-ion battery would do.

I also included the files for the 3d printed case that I made. I used a glue gun and glue sticks to hold most of the components and wiring in place. Please see my website for tutorials about how it was put together.

The hardware used was specifically selected because it is all open source hardware.

“Open source hardware is hardware whose design is made publicly available so that anyone can study, modify, distribute, make, and sell the design or hardware based on that design.”

# License

My portion of the software is licensed under the Apache2.0 license:

Copyright 2019 by AlaskaLinuxUser (https://thealaskalinuxuser.wordpress.com)

Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The software includes three libraries:

– The Adafruit Phona Library – Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution. Which was modified by Botletics, maintaining the BSD license.
– The PCD8544 Library – The MIT License (MIT), Copyright (c) 2013 Carlos Rodrigues <cefrodrigues@gmail.com>
– The Arduino software serial library – GPL2.0

Linux – keep it simple.

LTE Project: GPS and Compass screens!

d

Another update on my LTE project. This one is fairly small, but I worked out the compass screen, which runs off of the GPS. You can see the whole commit here.  What is interesting about this is that I actually edited the library for the LTE shield itself to do what I wanted. Fortunately, it was pretty simple.

The problem is space. I’m running out of dynamic memory. I need to maintain around 500 bytes to run the sketch, but it is difficult when I start adding variables. The Arduino Uno only has 2 kb of ram. So, to call the GPS to get the heading, you need this:

boolean Adafruit_FONA::getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude,
uint16_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, float *sec) {

But I only had room for one more float variable. But I found this in the library:

// only grab altitude if needed
if (altitude != NULL) {
// grab altitude
char *altp = strtok(NULL, “,”);
if (! altp) return false;
*altitude = atof(altp);
}

What does that mean? Well, a lot of variables in the above are allowed to be “null” or nothing. So, I edited the libraries/Botletics_SIMCom_Library_v1.0.0/Adafruit_FONA.h file from this:

boolean getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude,

To this:

boolean getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude = NULL,

Claiming the altitude is null. This is perfect because I can call one float, named heading, and then call the method with just one float instead of a bunch of them. Like this:

case 4:{ // Compass screen
                float heading;
                if (fona.getGPS(&heading, &heading, &heading, &heading)) {
                  lcd.setCursor(0, 1);
                  lcd.print("Heading: "); lcd.print(heading);
                }

So, even though I technically need a float for lat, long, heading, and altitude, now I am just using the heading one and letting it be overwritten by lat, long, etc., and the last one written is the heading! Yes, this is cheating, but praise God, it worked! This LTE project is really coming along!

Linux – keep it simple.

LTE Project: SMS, read and reply!

Of course the Botletics shield that houses the modem was able to receive sms messages the moment I put a sim card in it, but now I can read them on my device! That’s right! Using nothing but the interface and buttons on the device, I can select which message to read, I can view it, and then reply or delete it!

Originally, I was going to have a scrolling screen that you could use the buttons to scroll through and read the text messages. This had several advantages, like being able to see a conversation flow. However, it had some disadvantages too. Namely, I don’t have enough memory left on this thing to hold the messages in the Arduino’s ram.

That said, I needed to just read the message and display it to the screen. I already have a buffer for sending a text message, and a buffer for what phone number to send it to (2 char arrays, the message one is 140, and the phone number is 21). This actually worked out in my favor greatly. With the read screen, you get to choose a message number to read, so I made a small int to hold that number and you can use up and down to change it, or move it by 10 with left and right.

Once you settle on the message to read, you press select, which then reads that message from line into the phone number send char array, and the from message into the send message char array. These are simply displayed on the screen.

With that done, it is actually really easy to delete the message, since you have a message number already, so selecting to delete it, it already knows which one to delete!

Also, replying becomes easy, since the send to phone number is already saved in the send to phone number char array! Also the text message is saved their too, so you can read the message you were sent while you write the new message. I think it is great! The only problem is this: if your wife texts you and says “what should we have for dinner tonight?”, when you hit reply, you have to overwrite that whole message so you can say, “tacos”. So I’m not sure, I may want to blank it out instead, but for now, it’s pretty hand for testing, since I can just hit reply and send the same message back for testing purposes.

Be sure to check out the entire commit for all the good details I missed here!

Linux – keep it simple.

LTE Project: Sent a text message!

Today was a great day for my LTE project! Today I sent a text message using only the buttons on the device itself! It was great to be able to do that from the gui/interface without the need for a serial over USB connection!

So, how does it work? Well, you can check out the entire commit on my GitLab, but I’ll highlight the main parts here. First, I needed a way to type with only 6 buttons, one of them permanently being the “home” button, and one always being the “select/ok” button. So really just 4 buttons. With that in mind, I made a simple interface that I’ve seen before: Up/Down to cycle through the letters/numbers, and Left/Right to move which place you are typing at.

To make that work, I added an array of characters that you can cycle through, like so:

char letterNumbers[91] = {'0','1','2','3','4','5','6','7','8','9',' ','A','B','C','D','E','F','G',
  'H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e',
  'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','`','~','!',
  '@','#','$','%','^','&','*','(',')','_','+','|','-','=',';',':',',','/','.','<','>','?'};

Notice that not every keyboard character is there. You have the forward slash, but not the back slash, due to an issue with char. I’m sure I can work it in, but I needed to get it working first, then I can edit it more later.

Then, I use a variable called curPos to mark which spot in the message you are, and numLetter to hold which number of the 91 characters you are trying to use. It looks like this:

case 30:{ // Screen 5 – Enter phone number screen.
// Up one character
if (numLetter >= 91){
numLetter = 0;
} else {
numLetter++;
}
break;
}
case 35:{
// Down one character
if (numLetter <= 0){
numLetter = 91;
} else {
numLetter–;
}
break;
}
case 40:{
// Left one position
if (curPos <= 0){
curPos = 0;
} else {
sendText[curPos] = letterNumbers[numLetter];
curPos–;
}
break;
}
case 45:{
// Right one position
if (curPos >= 21){
curPos = 21;
} else {
sendText[curPos] = letterNumbers[numLetter];
curPos++;
}
break;
}

It allows you to wrap around from character 91 back to character 0 in the list. Then when you press left or right, it saves the character you chose, say “A” in the spot where you were! It’s a little cumbersome, but it actually works!

The only thing I wonder is if the left button should be like delete, and leave a blank space instead of writing the current character and going left. I’m not sure which works better. I suppose a smart person can actually write the entire text backwards if they mess up and want to retype it…. maybe not.

It can be a little confusing, because it doesn’t save the letter/number/punctuation you have chosen until you move left or right, which appears like it is there, but it is not saved until you move off of it. You also can’t read what is under the “cursor” because it always displays the current chosen character you want to write. I’ll look at ways to fix that, but for now, it’s pretty functional, just not very pretty.

Linux – keep it simple.

LTE Project: Button it up.

Now that I shoved all the wires in there and soldered in the connections for the buttons, I was able to close the case. It still opens, you just have to unscrew the 4 screws to take it apart.

With that, I’ve also made progress on the button reading and programming. As we saw before, the program uses a “truth table” where based on the math formula of (btn# + screenNumber)*screenNumber = menu option, we can calculate all possible outputs and assign them to operations or values.

So, this is a compilation of four different commits:

  1. Update the truth table and screens.
  2. Adding button reading.
  3. Screen updates.
  4. Some small updates.

You can check out all of the above commits to see the process, but here I’ll cover the main part. This is the button reading function.

int read_LCD_buttons(){               // read the buttons
  adc_key_in = 0;
    //adc_key_in = analogRead(A0);       // read the value from the sensor 
    Serial.print("anolog0:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnRIGHT;
    //adc_key_in = analogRead(A1);       // read the value from the sensor 
    Serial.print("anolog1:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnUP;
    adc_key_in = analogRead(A2);       // read the value from the sensor 
    Serial.print("anolog2:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnDOWN;
    adc_key_in = analogRead(A3);       // read the value from the sensor 
    Serial.print("anolog3:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnLEFT;
    adc_key_in = analogRead(A4);       // read the value from the sensor 
    Serial.print("anolog4:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnSELECT;
    adc_key_in = analogRead(A5);       // read the value from the sensor 
    Serial.print("anolog5:"); Serial.println(adc_key_in);
    if (adc_key_in > 550)   return btnBACK; 
    return btnNONE;                // when all others fail, return this.
}

At first, I have it log everything to serial so I can see what is happening. Essentially, I took a wire from 3.3vdc that goes to the button. Then the button goes to the analog input, with a jumper going to a resistor to ground. That way, when you are not pushing the button, then the analog pin is not floating, and reads 0. When you push a button, that input reads around 700. So, I put the threshold at greater than 550. This seems to work fairly well.

The only problem is that I didn’t arrange the buttons the way I thought that I was programming them to work. Rather than swap the button wires physically, I just re-ordered them in my program, saying one was two, etc.

Here is the call inside the loop, asking for which button is pressed:

int waiting = 0;
menuNumber = 0;
while ( waiting < 30 ){
waiting++;
delay(10);
lcd_key = read_LCD_buttons(); // read the buttons
// TESTING ONLY // Serial.print(lcd_key);
switch (lcd_key){

case btnUP:{
menuNumber = (1+screenNumber)*screenNumber;
break;
}
case btnDOWN:{
menuNumber = (2+screenNumber)*screenNumber;
break;
}
case btnLEFT:{
menuNumber = (3+screenNumber)*screenNumber;
break;
}
case btnRIGHT:{
menuNumber = (4+screenNumber)*screenNumber;
break;
}
case btnSELECT:{
menuNumber = 255;
break;
}
case btnBACK:{
menuNumber = 256;
break;
}
}
// TESTING ONLY // Serial.print(menuNumber);
}

The above call checks every 10 milliseconds to see if you pressed a button. After 30 checks, it continues through the process and refreshes the screens, etc. This works out to be about a half second, due to the length of the program. There is a small window of about a tenth of a second, where pushing a button doesn’t do anything, but I’ve found in test runs that it was really rare that pushing a button didn’t respond immediately.

If you don’t do this, it is refreshing the screen about 30 times a second as it rips through the program, and there is only a fraction of a second where pushing the button actually works. There is probably a better way to do this, but this works really well for my program.

Now I just need to make it send and receive text messages!

Linux – keep it simple.

LTE project button code

lteprojecta

Here’s the deal, I have a very small screen, with six available buttons. I need to make sure that if you press the button, it does the right thing for the screen it is currently on. How do I map the six buttons to the specific screen I’m on, with only 32 kb of programming space?

Well, brilliant or butchered, here’s what I did….

First, I decided on the flow of screens. Example, from the main screen (screen number 1), you can go to the texting screen (sn 6) or GPS screen (sn 3) or the “other programs” screen (sn 12). From the GPS screen, you can go to the location screen (sn 2), or the compass screen (sn 4). And from the texting screen, you can go to the read messages screen (sn 9), or the send messages screen (sn 7), the delete all messages screen (sn 8), and so on and so forth. All told, there is around 15 screens currently.

But how to map pushing the same four buttons for each screen number? There are probably better ways to do this, but I came up with a mathematical formula and a switch to handle this for me.

sn Button 1 Button 2 Button 3 Button 4 Button 5 Button 6
1 2 3 4 5
2 6 8 10 12
3 12 15 18 21
4 20 24 28 32
5 30 35 40 45
6 42 48 54 60
7 56 63 70 77
8 72 80 88 96
9 90 99 108 117
10 110 120 130 140
11 132 143 154 165
12 156 168 180 192
13 182 195 208 221
14 210 224 238 252
15 240 255 270 285
16 272 288 304 320
17 306 323 340 357
18 342 360 378 396
19 380 399 418 437

What the above table does, is utilize the following formula: “Screen number plus Button number is multiplied by Screen number.” With this formula, I then used the variable screen number, which I need for what screen text to display anyways, and made a switch that checks the math to see what button I am pushing. What is interesting about this is that you technically could do any operation from any screen, but the screen number will make the math work only for the operations you should do on that screen.

As you can see, screen number 2 and screen number 3 both share the number 12. In my small table, it is the only occurrence of the same number twice. Fortunately, it is okay, because I made screen 2 the location screen, which you get to from screen 3. So pushing that first button on screen 3 takes you mathematically to screen 2, and on screen 2, pressing the last button takes you mathematically to screen 2, which is where location information is displayed. So it is a little sloppy, but works out in the end.

Buttons 5 and 6 don’t work that way, though. They are special buttons that always return the same two numbers. The first one is the “home” button, which from any screen takes you back to the main menu. The second is the “select” button, which will be unique in use and will have to have a special case by case use. It’s actually not used on any screens thus far, so it is held in reservation for now. I was thinking of making it a modem power on/off switch, but we will see.

As always, you can check out the commit on my GitLab.

Linux – keep it simple.

Arduino Asteroids Game: Randomly!

game3

I wanted to post a video, but sadly the free version of WordPress doesn’t allow this. So, you can click here to watch the video of me playing “Asteroids Game!” on my Uno with the LCD Keypad Shield. Sorry for the low quality of the video, but I’m sure you’ll enjoy it all the same.

The game is complete, and you are welcome to head over to my GitLab and download the ino file and compile it yourself. Remember, you will need the LCD Keypad Shield library as well. Some stats about the game and program:

Sketch uses 7510 bytes (23%) of program storage space. Maximum is 32256 bytes.
Global variables use 473 bytes (23%) of dynamic memory, leaving 1575 bytes for local variables. Maximum is 2048 bytes.

Also, the entire game is programmed in less than 600 lines (would be significantly less without all the explanation blocks I put in there), and the ino file is less than 20 kb!

One of the biggest parts of the game is making sure that the asteroids show up in a random fashion. With only 4 asteroids, it is important that the pattern is not discernible by the player, or they will easily be able to win over and over again. Here is how I called it:

gameAsteroidOne = get_random(4);

I am calling the “get_random” function with an integer (in this case) of 4. That will make more sense once I show you the function:

int get_random (int addOn) {
srand(millis()+addOn); // Use time since turned on and add on number as seed for random number.
int r = rand() % 10; // Returns a random integer between 0 and 10.
r += 10; // Add 10 to keep it off of the display screen.
return r;
}

You see, computers can’t actually make random numbers, so you have to “seed” it with something to grow a number from. As a “seed” I input the time in milliseconds that the game has been running. From this it makes a “random” number from 1 to 10. It then adds 10 to that number to place the asteroid off of the screen, giving the appearance that it existed before and slowly came into view.

The problem is that sometimes the game loop runs fast enough where two asteroids are asking for a new random number at the exact same time. If they do, they will both receive the exact same “random” number. This will cause them to “overlap” or be in the same physical spot, which means that they will both go off screen at the same time, and request a new random number at the same time, receiving the same “random” number again. It’s a loop.

To solve this, I added the integer “addOn” to the milliseconds to make a new number. This “addOn” number is passed with each asteroid, and each one has a different number, creating a new instance of “seed” for the random number generator. That way no two should return the exact same “random” number. Although it can still happen.

Just like rolling two dice can sometimes give you the same number, the random function can still randomly return the same number. The smaller the number pool, a six sided dice would have a pool of 6, our game has a pool of 10, the more likely a repeat of a random number happens.

Another case scenario is when asteroid one, for say, goes off screen, while asteroid two is 2 steps behind. Asteroid one gets a random number of, let’s say 6, which added to 10 makes 16. Now the asteroids move. One is 15, two is 1. Then one is 14, and two is 0. Then one is 13, and two falls off screen, getting a new number, which randomly could be 3, which, when added to 10, makes 13, and the two asteroids now occupy the same space.

A programmer could add a check for this, and if the asteroids are in the same space, cause a new random number to be chosen, or add or subtract a number to it, but in this simple game, it happens so rarely that it isn’t really a problem. The player just gets a bonus when those two asteroids pass next time.

Either way, I hope that you have enjoyed the game itself, and more so the creation of it. The game is open source and feel free to put it to good use!

Linux – keep it simple.