├── LICENSE.txt ├── README.md ├── antenna.go ├── assembly ├── KIT.md ├── README.md ├── antenna.md ├── backpack.md ├── ears-cables.md ├── images │ ├── antenna │ │ ├── led-connect1.png │ │ ├── led-connect2.png │ │ ├── led-crimp.png │ │ ├── spring-bottom1.png │ │ ├── spring-led.png │ │ ├── spring-top.png │ │ ├── spring1.png │ │ └── spring2.png │ ├── backpack │ │ ├── add-backpack.png │ │ ├── add-battery.png │ │ ├── attach-cpe.png │ │ ├── cut-cords.png │ │ ├── pass-cords.png │ │ └── pass-cords2.png │ ├── helmet │ │ ├── tie-wrap1.png │ │ ├── tie-wrap2.png │ │ ├── tie-wrap3.png │ │ └── tie-wrap4.png │ ├── kit │ │ ├── 10mm-screws.png │ │ ├── 6mm-screws.png │ │ ├── antenna-lock-washers.png │ │ ├── antenna-washers.png │ │ ├── backpack.png │ │ ├── circuit-playground-express.png │ │ ├── connectors.png │ │ ├── ears.png │ │ ├── elastic.png │ │ ├── female-bayonet.png │ │ ├── gel-strip.png │ │ ├── helmet.png │ │ ├── led-strip.png │ │ ├── led.png │ │ ├── m3-nuts.png │ │ ├── m3-washers.png │ │ ├── male-bayonet.png │ │ ├── plushie.png │ │ ├── ribbon.png │ │ ├── spring.png │ │ ├── terminals.png │ │ ├── tie-wrap.png │ │ └── usb.png │ ├── tools │ │ ├── battery.png │ │ ├── crimper.png │ │ ├── cutter.png │ │ ├── scissors.png │ │ ├── screwdriver.png │ │ └── tape.png │ └── visor │ │ ├── connect-cpe-fork1.png │ │ ├── connect-cpe-fork2.png │ │ ├── connect-cpe-fork3.png │ │ ├── crimp-ribbon-fork.png │ │ ├── crimp-ribbon-green.png │ │ ├── crimp-ribbon-ground.png │ │ ├── crimp-ribbon-rgb.png │ │ ├── crimp-ribbon-rgb3.png │ │ ├── cut-ribbon-cable.png │ │ ├── place-gel-strip.png │ │ ├── place-rgb-led.png │ │ ├── rgb-led-connector.png │ │ ├── route-wires.png │ │ ├── strip-ribbon-cable.png │ │ └── trim-rgb-wires.png ├── rgb-led.md └── visor.md ├── backpack.go ├── buttons.go ├── examples ├── backpack │ └── main.go ├── ble-advertiser │ └── main.go ├── blink-all │ └── main.go ├── blink │ └── main.go ├── demo │ └── main.go ├── findmy │ ├── README.md │ ├── beacon.go │ └── main.go ├── sensors │ └── main.go ├── speaker │ └── main.go └── visor │ └── main.go ├── go.mod ├── go.sum ├── gopherbot.go ├── learn ├── README.md ├── step0 │ └── main.go ├── step1 │ └── main.go ├── step2 │ └── main.go ├── step3 │ └── main.go ├── step4 │ └── main.go ├── step5 │ └── main.go ├── step6 │ └── main.go ├── step7 │ └── main.go ├── step8 │ └── main.go └── step9 │ └── main.go ├── led.go ├── sensors.go ├── slider.go ├── speaker.go ├── speaker_bluefruit.go ├── speaker_express.go └── visor.go /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018-2022 The Hybrid Group 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gopherbot 2 | 3 | Gopherbot is a robot gopher plushie that is programmable using TinyGo (https://tinygo.org) 4 | 5 | [![GoDoc](https://godoc.org/github.com/hybridgroup/gopherbot?status.svg)](https://godoc.org/github.com/hybridgroup/gopherbot) 6 | 7 | Uses an [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333) with a 3D printed helmet and backpack. 8 | 9 | Here is a TinyGo program that blinks all of the various built-in LEDs all at the same time when the slider switch is in the "on" position. 10 | 11 | ```go 12 | package main 13 | 14 | import ( 15 | "time" 16 | 17 | "github.com/hybridgroup/gopherbot" 18 | ) 19 | 20 | func main() { 21 | led := gopherbot.StatusLED() 22 | antenna := gopherbot.Antenna() 23 | visor := gopherbot.Visor() 24 | backpack := gopherbot.Backpack() 25 | 26 | slider := gopherbot.Slider() 27 | 28 | for { 29 | if slider.IsOn() { 30 | led.On() 31 | antenna.On() 32 | visor.Blue() 33 | backpack.Blue() 34 | time.Sleep(500 * time.Millisecond) 35 | 36 | led.Off() 37 | antenna.Off() 38 | visor.Off() 39 | backpack.Off() 40 | time.Sleep(500 * time.Millisecond) 41 | } 42 | } 43 | } 44 | ``` 45 | 46 | ## Assembling Your Kit 47 | 48 | Did you receive a Gopherbot kit? Awesome! For assembly instructions, go here: 49 | 50 | [Gopherbot Assembly Instructions](./assembly/README.md) 51 | 52 | The 3D designs for the helmet, ears, and backpack are created by Damen Evans under the Creative Commons - Attribution - Non-Commercial license. The files are located here: 53 | 54 | https://www.thingiverse.com/thing:3761937 55 | 56 | ## Installation 57 | 58 | To put code on Gopherbot, you need to install some software on your own machine. 59 | 60 | ### Go 1.18 61 | 62 | If you have not installed Go 1.18 on your computer already, you can download it here: 63 | 64 | https://golang.org/dl/ 65 | 66 | ### TinyGo 67 | 68 | Follow the instructions here to install TinyGo: 69 | 70 | https://tinygo.org/getting-started/ 71 | 72 | ### Gopherbot code 73 | 74 | Lastly, get the code from this repository: 75 | 76 | ``` 77 | git clone https://github.com/hybridgroup/gopherbot.git 78 | cd gopherbot 79 | ``` 80 | 81 | OK great, we're ready to write our first TinyGo program and put it on Gopherbot. 82 | 83 | ## Hello, Gopherbot 84 | 85 | Gopherbot uses an [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333) as its "brain". To put new code on the Circuit Playground Express you can copy a file in the correct format from your computer to the board using a USB connection without having to install any extra flashing software. This is because it comes with a "bootloader" named UF2 already installed, that lets to do the flashing. Here is more information about the [UF2 bootloader](https://github.com/Microsoft/uf2) if you are interested. 86 | 87 | Here is what to do: 88 | 89 | - Plug your Circuit Playground Express into your computer's USB port. 90 | - Build and flash your TinyGo program to the board in `.uf2` format using this command: 91 | 92 | ```shell 93 | tinygo flash -target=gopherbot examples/blinky1 94 | ``` 95 | 96 | - The Circuit Playground Express board should restart and then begin running your program. This program just causes the small LED labelled "D13" on the Circuit Playground Express board to start blinking on and off. 97 | 98 | Now you are ready to try something a little more flashy. 99 | 100 | - Build and flash the demo TinyGo program to the board using this command: 101 | 102 | ```shell 103 | tinygo flash -target=circuitplay-express ./examples/blink/ 104 | ``` 105 | 106 | Now THAT is a blink! 107 | 108 | ## What To Do Next? 109 | 110 | If you want to load one of the example programs on Gopherbot, check out our [examples located here](./examples). 111 | 112 | For a series of activities to learn programming TinyGo using Gopherbot, check out the [learn folder](./learn/README.md). 113 | 114 | Have fun! 115 | 116 | ## Gopherbot 2 117 | 118 | The Gopherbot 2 is the same as the Gopherbot but uses a Circuit Playground Bluefruit board, which has a Nordic Semiconductors nrf52840 processor with built-in Bluetooth radio. 119 | 120 | To flash code on the Gopherbot 2, use the same commands but with the `target=gopherbot2`. 121 | 122 | ```shell 123 | tinygo flash -target=gopherbot2 ./examples/blink/ 124 | ``` 125 | -------------------------------------------------------------------------------- /antenna.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "machine" 5 | "time" 6 | ) 7 | 8 | // AntennaDevice controls the LED of the Gopherbot Helmet's antenna. 9 | type AntennaDevice struct { 10 | LEDDevice 11 | } 12 | 13 | // Antenna returns a the Antenna to control the Gopherbot Antenna LED. 14 | func Antenna() *AntennaDevice { 15 | led := machine.A2 16 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 17 | 18 | return &AntennaDevice{ 19 | LEDDevice: LEDDevice{ 20 | Pin: led, 21 | Speed: 500 * time.Millisecond, 22 | }, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assembly/KIT.md: -------------------------------------------------------------------------------- 1 | # Gopherbot Kit Parts 2 | 3 | The Gopherbot kit consists of the following parts: 4 | 5 | ### Helmet 6 | ![Kit](./images/kit/helmet.png) 7 | 8 | ### Helmet - Ears 9 | ![Kit](./images/kit/ears.png) 10 | 11 | ### Backpack 12 | ![Kit](./images/kit/backpack.png) 13 | 14 | ### Circuit Playground Express board 15 | ![Kit](./images/kit/circuit-playground-express.png) 16 | 17 | ### Plushie 18 | ![Kit](./images/kit/plushie.png) 19 | 20 | ### RGB LED Strip 21 | ![Kit](./images/kit/led-strip.png) 22 | 23 | ### Antenna Spring 24 | ![Kit](./images/kit/spring.png) 25 | 26 | ### Antenna Washers 27 | ![Kit](./images/kit/antenna-washers.png) 28 | 29 | ### Antenna Lock Washers 30 | ![Kit](./images/kit/antenna-lock-washers.png) 31 | 32 | Antenna Spring (90mm length, 6mm diameter + 2 M5 locking washers) 33 | 34 | ### Wired LED w/resistor 35 | ![Kit](./images/kit/led.png) 36 | 37 | Your kit includes five different colors of pre-wired LED w/resistor. 38 | 39 | ### Gel strip 40 | ![Kit](./images/kit/gel-strip.png) 41 | 42 | Gel strip for visor 43 | 44 | ### USB Cable 45 | ![Kit](./images/kit/usb.png) 46 | 47 | ### 2 female bayonet connectors 48 | ![Kit](./images/kit/female-bayonet.png) 49 | 50 | ### 2 male bayonet connectors 51 | ![Kit](./images/kit/male-bayonet.png) 52 | 53 | ### 3 solderless connectors 54 | ![Kit](./images/kit/connectors.png) 55 | 56 | ### 4 fork terminals 57 | ![Kit](./images/kit/terminals.png) 58 | 59 | ### Ribbon cable 60 | ![Kit](./images/kit/ribbon.png) 61 | 62 | ### 10mm Machine screws 63 | ![Kit](./images/kit/10mm-screws.png) 64 | 65 | 6 M3 10mm machine screws 66 | 67 | ### 6mm Machine screws 68 | ![Kit](./images/kit/6mm-screws.png) 69 | 70 | 8 M3 6mm machine screws 71 | 72 | ### M3 nuts 73 | ![Kit](./images/kit/m3-nuts.png) 74 | 75 | 14 M3 nuts 76 | 77 | ### M3 washers 78 | ![Kit](./images/kit/m3-washers.png) 79 | 80 | 4 M3 washers 81 | 82 | ### Elastic 83 | ![Kit](./images/kit/elastic.png) 84 | 85 | ### Tie Wraps 86 | ![Kit](./images/kit/tie-wrap.png) 87 | -------------------------------------------------------------------------------- /assembly/README.md: -------------------------------------------------------------------------------- 1 | # Assembling Your Gopherbot Kit 2 | 3 | Here are instructions on how to assemble your Gopherbot kit. 4 | 5 | ## Preparation 6 | 7 | ### Check Your Parts 8 | 9 | Start by verifying that you have all your parts. Take a look at the list of [kit parts](./KIT.md). 10 | 11 | ### Things You Need That Are Not In The Kit 12 | 13 | There are several items you will need that are not included in the Gopherbot kit: 14 | 15 | #### 5V USB Battery 16 | 17 | ![Tools](./images/tools/battery.png) 18 | 19 | Your basic 5V rechargable battery. 20 | 21 | #### Black electrical tape 22 | 23 | ![Tools](./images/tools/tape.png) 24 | 25 | Black electrical tape (approx 40mm wide and 100mm in length). You can also use black duct tape. 26 | 27 | #### Wire cutter/stripper 28 | 29 | ![Tools](./images/tools/cutter.png) 30 | 31 | #### Wire crimper 32 | 33 | ![Tools](./images/tools/crimper.png) 34 | 35 | #### Scissors 36 | 37 | ![Tools](./images/tools/scissors.png) 38 | 39 | #### Small Phillips head screwdriver 40 | 41 | ![Tools](./images/tools/screwdriver.png) 42 | 43 | ## Assembly 44 | 45 | ### Helmet - Visor 46 | 47 | The helmet has an LED-filled visor. 48 | 49 | Here are the [visor assembly instructions](./visor.md). 50 | 51 | ### Helmet - Antenna 52 | 53 | Now that the visor is installed, it is time to attach the antenna to the helmet. 54 | 55 | Here are the [antenna assembly instructions](./antenna.md). 56 | 57 | ### Helmet - Ears and cables 58 | 59 | Attach the ears, and then tie wrap the cables neatly to the helmet. 60 | 61 | Here are the [ears and cables assembly instructions](./ears-cables.md). 62 | 63 | ### Backpack 64 | 65 | Now it is time to assemble the 3D printed backpack. 66 | 67 | Here are the [backpack assembly instructions](./backpack.md). 68 | 69 | ### Putting on the helmet and backpack 70 | 71 | You should now be ready to put the helmet and backpack on your plushie. 72 | 73 | ### Next steps 74 | 75 | Now that your Gopherbot is fully assembled, go back to the main README and continue with the software installation on your computer so you can write your own programs. 76 | -------------------------------------------------------------------------------- /assembly/antenna.md: -------------------------------------------------------------------------------- 1 | # Helmet - Antenna 2 | 3 | Now that the visor is installed, it is time to attach the antenna to the helmet. 4 | 5 | ## Screw first locking washer onto spring 6 | 7 | ![Kit](./images/antenna/spring1.png) 8 | 9 | Screw one of the M6 locking washers to around 1.5 cm up the spring. 10 | 11 | ## Slide flat washer onto spring 12 | 13 | ![Kit](./images/antenna/spring2.png) 14 | 15 | Slide one of the flat washers up the spring until it is flat against the locking washer. 16 | 17 | ## Slide the spring into the top of the helmet 18 | 19 | ![Kit](./images/antenna/spring-top.png) 20 | 21 | Slide the spring into the top of the helmet up to the flat washer. 22 | 23 | ## Slide second flat washer onto spring 24 | 25 | ![Kit](./images/antenna/spring-bottom1.png) 26 | 27 | Slide second flat washer onto spring from *inside the helmet*. 28 | 29 | ## Screw second locking washer onto spring 30 | 31 | Screw second locking washer onto spring from *inside the helmet*. 32 | 33 | ## Insert LED with resistor thru spring from top 34 | 35 | ![Kit](./images/antenna/spring-led.png) 36 | 37 | Insert the LED with pre-wired resistor into the spring from the top, and carefully pull thru until the LED is as even as possible with the top of the spring. It does not need to be pulled very tight. You probably will not be able to pull it all the way, just pull util it cannot go any further. 38 | 39 | ## Connect female bayonet connectors to LED 40 | 41 | Use your wire strippers to strip off the insulation of the last 7mm of each of the wires on the ends of the red and black wires on the LED leaving the bare wires exposed. 42 | 43 | ![Kit](./images/antenna/led-connect1.png) 44 | 45 | Crimp one of female bayonet terminals to the black wire on the LED with your crimpers. Make sure to push the wire into the bayonet terminal so that the bare wire is sticking thru slightly, but not all the way thru. 46 | 47 | Crimp one of female bayonet terminals to the red wire on the LED with your crimpers, in the same way that you crimped the black wire. 48 | 49 | ## Connect male bayonet connectors to ribbon cable 50 | 51 | Use your wire strippers to strip off the insulation of the last 7mm of the blue and black wires on the ribbon cable, which should be the only wires on the ribbon cable that are not yet connected. Make sure to leave the bare wires exposed. 52 | 53 | ![Kit](./images/antenna/led-crimp.png) 54 | 55 | Crimp one of male bayonet terminals to the black wire on the ribbon cable with your crimpers. Make sure to push the wire into the bayonet terminal so that the bare wire is sticking thru slightly, but not all the way thru. 56 | 57 | Crimp one of male bayonet terminals to the blue wire on the ribbon cable with your crimpers, in the same way that you crimped the black wire. 58 | 59 | ## Plug male bayonet connectors into female bayonet connectors 60 | 61 | ![Kit](./images/antenna/led-connect2.png) 62 | 63 | Plug the male bayonet connector from the black wire on the ribbon cable into the female connector on the black wire on the LED. 64 | 65 | Plug the male bayonet connector from the blue wire on the ribbon cable into the female connector on the red wire on the LED. 66 | 67 | ## Next step 68 | 69 | Now you are ready to proceed by tie wrapping the cables neatly to the helmet, and then attaching the ears. 70 | 71 | Here are the [ears and cables assembly instructions](./ears-cables.md). 72 | -------------------------------------------------------------------------------- /assembly/backpack.md: -------------------------------------------------------------------------------- 1 | # Backpack 2 | 3 | Now it is time to complete the 3D printed backpack. 4 | 5 | ## Cut elastic backpack straps 6 | 7 | Cut the elastic cord to make the backpack straps. 8 | 9 | ![Kit](./images/backpack/cut-cords.png) 10 | 11 | Cut two pieces that are 23 cm long. 12 | 13 | Cut two pieces that are 13 cm long. 14 | 15 | ## Tie on nylon backpack straps 16 | 17 | ![Kit](./images/backpack/pass-cords.png) 18 | 19 | Pass the end of the first longer elastic strap thru both top holes on one side of the backpack. Tie an overhand knot on each end and tie the two ends together. 20 | 21 | ![Kit](./images/backpack/pass-cords2.png) 22 | 23 | Pass the end of the second longer elastic strap thru both top holes on the other side of the backpack. Tie an overhand knot on each end and tie the two ends together. 24 | 25 | Pass the end of the first shorter elastic strap thru both bottom holes on one side of the backpack. Tie an overhand knot on each end and tie the two ends together. 26 | 27 | Pass the end of the second shorter elastic strap thru both bottom holes on one side of the backpack. Tie an overhand knot on each end and tie the two ends together. 28 | 29 | ## Attach Circuit Playground Express to backpack 30 | 31 | ![Kit](./images/backpack/attach-cpe.png) 32 | 33 | Finish attaching the Circuit Playground Express to backpack using four 10mm machine screws, four M3 washers, and four M3 nuts. 34 | 35 | Slip a washer between the back of the board and the standoff, then pass one 10mm machine screw thru the front of the circuit board. 36 | 37 | Screw a nut loosely on the back of the machine screw just enough so it does not fall off. It will be tightened down in an upcoming step. 38 | 39 | Now attach the remaining machine screws, washers, and nuts, in the same way that you did the first one. 40 | 41 | Once all four screws are in place, you can tighten them completely. 42 | 43 | The idea is that since there are 2 fork terminals that are connected between the back of the Circuit Playground Express and the standoffs on the backpack, we need the 4 washers to act as spacers so that the Circuit Playground Express board sits evenly on all 6 of the standoffs. 44 | 45 | ## Put the helmet and backpack on plushie 46 | 47 | ![Kit](./images/backpack/add-backpack.png) 48 | 49 | Place the helmet on the plushie's head, and place the backpack on using the elastic straps. 50 | 51 | ## Attach USB battery 52 | 53 | ![Kit](./images/backpack/add-battery.png) 54 | 55 | Attach the USB battery to the backpack by using the bottom elastic straps. Make sure the USB's connector is on the left hand side. 56 | 57 | ## Next steps 58 | 59 | Plug in the battery. Your Gopherbot should light up. You are ready to play! 60 | 61 | Now that your Gopherbot is fully assembled, go back to the main [README](../README.md) and perform the software installation on your computer so you can write your own programs. 62 | -------------------------------------------------------------------------------- /assembly/ears-cables.md: -------------------------------------------------------------------------------- 1 | # Helmet - Ears and cables 2 | 3 | Tie wrap the cables neatly to the helmet, and then attach the ears. 4 | 5 | ## Feed tie wraps to thru helmet 6 | 7 | ![Kit](./images/helmet/tie-wrap1.png) 8 | 9 | Feed the tie wraps thru the small holes in the back of the helmet, starting from the inside. 10 | 11 | ![Kit](./images/helmet/tie-wrap2.png) 12 | 13 | ## Route ribbon cable thru channel 14 | 15 | ![Kit](./images/helmet/tie-wrap3.png) 16 | 17 | Fold the ribbon cable gently, and then insert in the channel in the back of the helmet. 18 | 19 | ## Use tie wraps to secure ribbon cable 20 | 21 | ![Kit](./images/helmet/tie-wrap4.png) 22 | 23 | Pull each tie wrap tight to hold the ribbon cable in place. You might need to slide the tie wrap to be able to tighten it down completely. 24 | 25 | Once the tie wraps are tightened, cut off the ends. 26 | 27 | ## Attach ears 28 | 29 | Slide the ears into the holes on the sides of the helmet. They will be snug, but should fit. Do not use too much force. 30 | 31 | ## Next steps 32 | 33 | Now it is time to finish assembling the 3D printed backpack. 34 | 35 | Here are the [backpack assembly instructions](./backpack.md). 36 | -------------------------------------------------------------------------------- /assembly/images/antenna/led-connect1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/led-connect1.png -------------------------------------------------------------------------------- /assembly/images/antenna/led-connect2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/led-connect2.png -------------------------------------------------------------------------------- /assembly/images/antenna/led-crimp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/led-crimp.png -------------------------------------------------------------------------------- /assembly/images/antenna/spring-bottom1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/spring-bottom1.png -------------------------------------------------------------------------------- /assembly/images/antenna/spring-led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/spring-led.png -------------------------------------------------------------------------------- /assembly/images/antenna/spring-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/spring-top.png -------------------------------------------------------------------------------- /assembly/images/antenna/spring1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/spring1.png -------------------------------------------------------------------------------- /assembly/images/antenna/spring2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/antenna/spring2.png -------------------------------------------------------------------------------- /assembly/images/backpack/add-backpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/add-backpack.png -------------------------------------------------------------------------------- /assembly/images/backpack/add-battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/add-battery.png -------------------------------------------------------------------------------- /assembly/images/backpack/attach-cpe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/attach-cpe.png -------------------------------------------------------------------------------- /assembly/images/backpack/cut-cords.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/cut-cords.png -------------------------------------------------------------------------------- /assembly/images/backpack/pass-cords.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/pass-cords.png -------------------------------------------------------------------------------- /assembly/images/backpack/pass-cords2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/backpack/pass-cords2.png -------------------------------------------------------------------------------- /assembly/images/helmet/tie-wrap1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/helmet/tie-wrap1.png -------------------------------------------------------------------------------- /assembly/images/helmet/tie-wrap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/helmet/tie-wrap2.png -------------------------------------------------------------------------------- /assembly/images/helmet/tie-wrap3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/helmet/tie-wrap3.png -------------------------------------------------------------------------------- /assembly/images/helmet/tie-wrap4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/helmet/tie-wrap4.png -------------------------------------------------------------------------------- /assembly/images/kit/10mm-screws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/10mm-screws.png -------------------------------------------------------------------------------- /assembly/images/kit/6mm-screws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/6mm-screws.png -------------------------------------------------------------------------------- /assembly/images/kit/antenna-lock-washers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/antenna-lock-washers.png -------------------------------------------------------------------------------- /assembly/images/kit/antenna-washers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/antenna-washers.png -------------------------------------------------------------------------------- /assembly/images/kit/backpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/backpack.png -------------------------------------------------------------------------------- /assembly/images/kit/circuit-playground-express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/circuit-playground-express.png -------------------------------------------------------------------------------- /assembly/images/kit/connectors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/connectors.png -------------------------------------------------------------------------------- /assembly/images/kit/ears.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/ears.png -------------------------------------------------------------------------------- /assembly/images/kit/elastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/elastic.png -------------------------------------------------------------------------------- /assembly/images/kit/female-bayonet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/female-bayonet.png -------------------------------------------------------------------------------- /assembly/images/kit/gel-strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/gel-strip.png -------------------------------------------------------------------------------- /assembly/images/kit/helmet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/helmet.png -------------------------------------------------------------------------------- /assembly/images/kit/led-strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/led-strip.png -------------------------------------------------------------------------------- /assembly/images/kit/led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/led.png -------------------------------------------------------------------------------- /assembly/images/kit/m3-nuts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/m3-nuts.png -------------------------------------------------------------------------------- /assembly/images/kit/m3-washers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/m3-washers.png -------------------------------------------------------------------------------- /assembly/images/kit/male-bayonet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/male-bayonet.png -------------------------------------------------------------------------------- /assembly/images/kit/plushie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/plushie.png -------------------------------------------------------------------------------- /assembly/images/kit/ribbon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/ribbon.png -------------------------------------------------------------------------------- /assembly/images/kit/spring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/spring.png -------------------------------------------------------------------------------- /assembly/images/kit/terminals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/terminals.png -------------------------------------------------------------------------------- /assembly/images/kit/tie-wrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/tie-wrap.png -------------------------------------------------------------------------------- /assembly/images/kit/usb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/kit/usb.png -------------------------------------------------------------------------------- /assembly/images/tools/battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/battery.png -------------------------------------------------------------------------------- /assembly/images/tools/crimper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/crimper.png -------------------------------------------------------------------------------- /assembly/images/tools/cutter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/cutter.png -------------------------------------------------------------------------------- /assembly/images/tools/scissors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/scissors.png -------------------------------------------------------------------------------- /assembly/images/tools/screwdriver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/screwdriver.png -------------------------------------------------------------------------------- /assembly/images/tools/tape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/tools/tape.png -------------------------------------------------------------------------------- /assembly/images/visor/connect-cpe-fork1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/connect-cpe-fork1.png -------------------------------------------------------------------------------- /assembly/images/visor/connect-cpe-fork2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/connect-cpe-fork2.png -------------------------------------------------------------------------------- /assembly/images/visor/connect-cpe-fork3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/connect-cpe-fork3.png -------------------------------------------------------------------------------- /assembly/images/visor/crimp-ribbon-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/crimp-ribbon-fork.png -------------------------------------------------------------------------------- /assembly/images/visor/crimp-ribbon-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/crimp-ribbon-green.png -------------------------------------------------------------------------------- /assembly/images/visor/crimp-ribbon-ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/crimp-ribbon-ground.png -------------------------------------------------------------------------------- /assembly/images/visor/crimp-ribbon-rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/crimp-ribbon-rgb.png -------------------------------------------------------------------------------- /assembly/images/visor/crimp-ribbon-rgb3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/crimp-ribbon-rgb3.png -------------------------------------------------------------------------------- /assembly/images/visor/cut-ribbon-cable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/cut-ribbon-cable.png -------------------------------------------------------------------------------- /assembly/images/visor/place-gel-strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/place-gel-strip.png -------------------------------------------------------------------------------- /assembly/images/visor/place-rgb-led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/place-rgb-led.png -------------------------------------------------------------------------------- /assembly/images/visor/rgb-led-connector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/rgb-led-connector.png -------------------------------------------------------------------------------- /assembly/images/visor/route-wires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/route-wires.png -------------------------------------------------------------------------------- /assembly/images/visor/strip-ribbon-cable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/strip-ribbon-cable.png -------------------------------------------------------------------------------- /assembly/images/visor/trim-rgb-wires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hybridgroup/gopherbot/7470aeb95a006395c0fcc02f1b8d84e103a86d17/assembly/images/visor/trim-rgb-wires.png -------------------------------------------------------------------------------- /assembly/rgb-led.md: -------------------------------------------------------------------------------- 1 | # RGB LED Strip 2 | 3 | If you run into problems with the RGB LED strip not lighting up, and you are certain you have connected it correctly, it might be an issue with the 3-pin solderless connector that was included with the Gopherbot kits. 4 | 5 | The + pin inside some of the 3-pin connectors is slightly misaligned. You might be able to just push or wiggle the RGB LED strip a little bit, and it might light up. If this works, you can secure the positioning with a small strip of electrical tape so that it stays lit. 6 | 7 | Otherwise, try the following procedure. 8 | 9 | First, open up the white plastic connector by gently opening the snap-catch on the side to open the lid. 10 | 11 | ![Kit](./images/visor/rgb-led-connector.png) 12 | 13 | Once opened, you should be able to visibly see if the + pin on the connector is properly aligned with the copper pad on the RGB LED strip itself. You can bend down the + pin inside the connector towards the other pins with something like a toothpick, so that it sits more directly on top of the RGB LED strip's copper pad labeled +. 14 | 15 | You might need to remove the LED strip, bend the pin into position, and then push the RGB LED strip back into place. 16 | 17 | Once you have corrected the + pin positioning, gently but firmly close the 3-pin connector back up so that it holds the RGB LED strip in place. Make sure the snap catch on the connector clicks shut, or the connector will not hold the RGB LED strip in place. 18 | 19 | If for any reason this does not work, please email me and I will mail you another LED strip/connector that has been soldered together. 20 | -------------------------------------------------------------------------------- /assembly/visor.md: -------------------------------------------------------------------------------- 1 | # Helmet - Visor 2 | 3 | The helmet has an LED-filled visor. In this section we will assemble it. 4 | 5 | You will need the small piece of tape to complete this assembly. The most permanent solution is to use a small bit of black duct tape. Other colors will also work, as you cannot see the tape from the outside of the helmet. 6 | 7 | You can also use other kinds of tape, as long as it sticks to the PLA material used on the helmet. For example, black electrical tape. 8 | 9 | Some kinds of tape that are known NOT to work well: gift wrapping tape, painters tape. 10 | 11 | ## Cut ribbon cable to proper lengths 12 | 13 | ![Kit](./images/visor/cut-ribbon-cable.png) 14 | 15 | Take the ribbon cable and separate the last 7cm of the ends. 16 | 17 | Cut the last 1 cm off of the blue wire. 18 | 19 | Cut the last 2 cm off of the green wire. 20 | 21 | Cut the last 3 cm off of the red wire. 22 | 23 | Do not cut the black or white wires. 24 | 25 | _Note: The unevenly-cut ends of the ribbon cable will be connected to the circuitboard. The even ends will be crimped to the LED wires._ 26 | 27 | ## Attach RGB LED Strip 3-pin connector to ribbon cable 28 | 29 | Take the ribbon cable and separate the last 3cm of the uncut (even) ends. 30 | 31 | ![Kit](./images/visor/trim-rgb-wires.png) 32 | 33 | Trim off the exposed wire tips on the ends of the RGB LED's 3 wire connector. 34 | 35 | ![Kit](./images/visor/crimp-ribbon-rgb.png) 36 | 37 | Crimp the red wire on the 3-pin connector to the red wire on the ribbon cable's uncut side using the solderless connector with your pliers. 38 | 39 | Crimp the white wire on the 3-pin connector to the white wire on the ribbon cable's uncut side using the solderless connector with your pliers. 40 | 41 | ![Kit](./images/visor/crimp-ribbon-rgb3.png) 42 | 43 | Crimp the yellow wire on the 3-pin connector to the green wire on the ribbon cable's uncut side using the solderless connector with your pliers. 44 | 45 | ## Crimp spade fork terminals to cut end of ribbon cable 46 | 47 | ![Kit](./images/visor/strip-ribbon-cable.png) 48 | 49 | Use your wire strippers to strip off the insulation of the last 7mm of each of the wires on the cut end of the ribbon cable, leaving the bare wires exposed. 50 | 51 | ![Kit](./images/visor/crimp-ribbon-fork.png) 52 | 53 | Crimp one of the fork terminals to the red wire on the ribbon cable's cut side with your crimpers. Make sure to push the wire all the way thru the fork terminal so that the bare wire is sticking thru slightly. 54 | 55 | ![Kit](./images/visor/crimp-ribbon-green.png) 56 | 57 | Crimp one of the fork terminals to the green wire on the ribbon cable's cut side with your crimpers. 58 | 59 | Crimp one of the fork terminals to the blue wire on the ribbon cable's cut side with your crimpers. 60 | 61 | ![Kit](./images/visor/crimp-ribbon-ground.png) 62 | 63 | Crimp both the white and black terminals using the last fork terminal. 64 | 65 | ## Attach ribbon cable green and blue wires to Circuit Playground Express 66 | 67 | Attach ribbon cable to Circuit Playground Express using the fork connectors. 68 | 69 | Take 2 of the 6mm machine screws and 2 of the M3 nuts. 70 | 71 | ![Kit](./images/visor/connect-cpe-fork1.png) 72 | 73 | Connect the green wire's fork connector to the back side of the Circuit Playground Express "A3" terminal using the 6mm machine screw and one of the M3 nuts. 74 | 75 | Connect the blue wire's fork connector to the back side of the Circuit Playground Express "A2" terminal using the 6mm machine screw and one of the M3 nuts. 76 | 77 | ## Attach ribbon cable red and black/white wires to Circuit Playground Express and backpack 78 | 79 | Attach ribbon cable to Circuit Playground Express using the fork connectors. 80 | 81 | Take 2 of the 6mm machine screws and 2 of the M3 nuts. 82 | 83 | ![Kit](./images/visor/connect-cpe-fork2.png) 84 | 85 | Connect the red wire's fork connector to the back side of the Circuit Playground Express "3.3V" terminal using the 10mm machine screw and one of the M3 nuts. 86 | 87 | ![Kit](./images/visor/connect-cpe-fork3.png) 88 | 89 | Connect the white and black wire's fork connector to the back side of the Circuit Playground Express "GND" terminal using the 10mm machine screw and one of the M3 nuts. 90 | 91 | ## Test the RGB LED strip 92 | 93 | Run the pre-loaded test program to make sure that the LEDs are wired correctly by plugging in the Circuit Playground Express to a battery or your computer's USB port. If the RGB LED strip does not light up, it might be due to a mis-aligned "+" connector inside the plastic housing. For information on how to correct this, [click here](./rgb-led.md). 94 | 95 | ## Place gel strip inside visor 96 | 97 | ![Kit](./images/visor/place-gel-strip.png) 98 | 99 | Peel off the protective coating from the small gel strip, and then place the gel strip inside the helmet into the small space inside the visor. You might need to use a small scissors to trim the edges so it can fit. 100 | 101 | _Note: If you received a kit the gel strip may be taped to the lid of the box._ 102 | 103 | ## Place LEDs inside visor 104 | 105 | ![Kit](./images/visor/place-rgb-led.png) 106 | 107 | Place the RGB LED strip on top of the gel strip from inside the helmet in the small space inside the visor. 108 | 109 | ## Tape down the LEDs/gel strip 110 | 111 | Carefully use the tape to finish taping down the LEDs/gel strip to the inside of the helmet. 112 | 113 | ## Route the wires around the inside of the helmet 114 | 115 | ![Kit](./images/visor/route-wires.png) 116 | 117 | Route the wires around the inside of the helmet, but do not attach them to anything yet. 118 | 119 | ## Next step 120 | 121 | Now that the visor is installed, it is time to attach the antenna to the helmet. 122 | 123 | Here are the [antenna assembly instructions](./antenna.md). 124 | -------------------------------------------------------------------------------- /backpack.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "image/color" 5 | "machine" 6 | 7 | "tinygo.org/x/drivers/ws2812" 8 | ) 9 | 10 | // BackpackDevice controls the Gopherbot Backpack LED. 11 | type BackpackDevice struct { 12 | ws2812.Device 13 | LED []color.RGBA 14 | alt bool 15 | } 16 | 17 | // Backpack returns a BackpackDevice to control Gopherbot Backpack. 18 | func Backpack() *BackpackDevice { 19 | neo := machine.NEOPIXELS 20 | neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) 21 | v := ws2812.New(neo) 22 | 23 | return &BackpackDevice{ 24 | Device: v, 25 | LED: make([]color.RGBA, BackpackLEDCount), 26 | } 27 | } 28 | 29 | // Show sets the Backpack to display the current LED array state. 30 | func (b *BackpackDevice) Show() { 31 | b.WriteColors(b.LED) 32 | } 33 | 34 | // Off turns off all the LEDs. 35 | func (b *BackpackDevice) Off() { 36 | b.Clear() 37 | } 38 | 39 | // Clear clears the Backpack LEDs. 40 | func (b *BackpackDevice) Clear() { 41 | b.SetColor(color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 42 | } 43 | 44 | // SetColor sets the Backpack LEDs to a single color. 45 | func (b *BackpackDevice) SetColor(color color.RGBA) { 46 | for i := range b.LED { 47 | b.LED[i] = color 48 | } 49 | 50 | b.Show() 51 | } 52 | 53 | // Red turns all of the Backpack LEDs red. 54 | func (b *BackpackDevice) Red() { 55 | b.SetColor(color.RGBA{R: 0xff, G: 0x00, B: 0x00}) 56 | } 57 | 58 | // Green turns all of the Backpack LEDs green. 59 | func (b *BackpackDevice) Green() { 60 | b.SetColor(color.RGBA{R: 0x00, G: 0xff, B: 0x00}) 61 | } 62 | 63 | // Blue turns all of the Backpack LEDs b;ue. 64 | func (b *BackpackDevice) Blue() { 65 | b.SetColor(color.RGBA{R: 0x00, G: 0x00, B: 0xff}) 66 | } 67 | 68 | // Xmas light style that rotates 69 | func (b *BackpackDevice) Xmas() { 70 | b.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0xff, B: 0x00}) 71 | } 72 | 73 | // Alternate the 2 colors. 74 | func (b *BackpackDevice) Alternate(color1, color2 color.RGBA) { 75 | b.alt = !b.alt 76 | for i := range b.LED { 77 | b.alt = !b.alt 78 | if b.alt { 79 | b.LED[i] = color1 80 | } else { 81 | b.LED[i] = color2 82 | } 83 | } 84 | 85 | b.Show() 86 | } 87 | -------------------------------------------------------------------------------- /buttons.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "machine" 5 | ) 6 | 7 | // ButtonDevice is a button. 8 | type ButtonDevice struct { 9 | machine.Pin 10 | } 11 | 12 | // Pushed checks to see if the button is being pushed. 13 | func (b *ButtonDevice) Pushed() bool { 14 | return b.Get() 15 | } 16 | 17 | // LeftButton returns the left ButtonDevice. 18 | func LeftButton() *ButtonDevice { 19 | left := machine.BUTTONA 20 | left.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) 21 | 22 | return &ButtonDevice{left} 23 | } 24 | 25 | // RightButton returns the right ButtonDriver. 26 | func RightButton() *ButtonDevice { 27 | right := machine.BUTTONB 28 | right.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) 29 | 30 | return &ButtonDevice{right} 31 | } 32 | -------------------------------------------------------------------------------- /examples/backpack/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | xmasJet 15 | ) 16 | 17 | const ( 18 | forward = iota 19 | backward 20 | ) 21 | 22 | func main() { 23 | backpack := gopherbot.Backpack() 24 | left := gopherbot.LeftButton() 25 | right := gopherbot.RightButton() 26 | 27 | mode := redJet 28 | 29 | for { 30 | if right.Pushed() { 31 | mode++ 32 | if mode > xmasJet { 33 | mode = greenJet 34 | } 35 | } 36 | 37 | if left.Pushed() { 38 | mode-- 39 | if mode < greenJet { 40 | mode = xmasJet 41 | } 42 | } 43 | 44 | switch mode { 45 | case greenJet: 46 | backpack.Green() 47 | case redJet: 48 | backpack.Red() 49 | case redRotate: 50 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 51 | case xmasJet: 52 | backpack.Xmas() 53 | } 54 | 55 | time.Sleep(200 * time.Millisecond) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /examples/ble-advertiser/main.go: -------------------------------------------------------------------------------- 1 | //go:build circuitplay_bluefruit 2 | // +build circuitplay_bluefruit 3 | 4 | package main 5 | 6 | import ( 7 | "image/color" 8 | "time" 9 | 10 | "github.com/hybridgroup/gopherbot" 11 | "tinygo.org/x/bluetooth" 12 | ) 13 | 14 | var adapter = bluetooth.DefaultAdapter 15 | 16 | func main() { 17 | must("enable BLE interface", adapter.Enable()) 18 | 19 | adv := adapter.DefaultAdvertisement() 20 | must("configure advertisement", adv.Configure(bluetooth.AdvertisementOptions{ 21 | LocalName: "Gopherbot", 22 | })) 23 | 24 | must("start advertising", adv.Start()) 25 | 26 | accel = gopherbot.Accelerometer() 27 | visor = gopherbot.Visor() 28 | speaker = gopherbot.Speaker() 29 | 30 | antenna := gopherbot.Antenna() 31 | backpack := gopherbot.Backpack() 32 | 33 | left := gopherbot.LeftButton() 34 | right := gopherbot.RightButton() 35 | 36 | mode := redVisor 37 | 38 | go antenna.Blink() 39 | 40 | for { 41 | if right.Pushed() { 42 | mode++ 43 | if mode > xmasVisor { 44 | mode = greenVisor 45 | } 46 | } 47 | 48 | if left.Pushed() { 49 | mode-- 50 | if mode < greenVisor { 51 | mode = xmasVisor 52 | } 53 | } 54 | 55 | switch mode { 56 | case greenVisor: 57 | visor.Green() 58 | backpack.Alternate(color.RGBA{R: 0x00, G: 0xff, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0xff}) 59 | case redVisor: 60 | visor.Red() 61 | backpack.Red() 62 | case cylonVisor: 63 | visor.Cylon() 64 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 65 | case tiltVisor: 66 | tilt() 67 | case xmasVisor: 68 | visor.Xmas() 69 | backpack.Xmas() 70 | } 71 | 72 | time.Sleep(200 * time.Millisecond) 73 | } 74 | } 75 | 76 | func must(action string, err error) { 77 | if err != nil { 78 | panic("failed to " + action + ": " + err.Error()) 79 | } 80 | } 81 | 82 | const ( 83 | greenVisor = iota 84 | redVisor 85 | cylonVisor 86 | tiltVisor 87 | xmasVisor 88 | ) 89 | 90 | const ( 91 | forward = iota 92 | backward 93 | ) 94 | 95 | var ( 96 | accel *gopherbot.AccelerometerDevice 97 | visor *gopherbot.VisorDevice 98 | speaker *gopherbot.SpeakerDevice 99 | 100 | pos = 0 101 | ) 102 | 103 | func tilt() { 104 | x, y, z, _ := accel.ReadAcceleration() 105 | println(x, y, z) 106 | 107 | switch { 108 | case x < 300000 && x > -300000: 109 | switch { 110 | case pos <= gopherbot.VisorLEDCount/2-1: 111 | pos++ 112 | case pos >= gopherbot.VisorLEDCount/2+1: 113 | pos-- 114 | } 115 | case x > 300000: 116 | pos++ 117 | if pos == gopherbot.VisorLEDCount { 118 | pos = gopherbot.VisorLEDCount - 1 119 | speaker.Bleep() 120 | } 121 | case x < -300000: 122 | pos-- 123 | if pos < 0 { 124 | pos = 0 125 | speaker.Bleep() 126 | } 127 | } 128 | 129 | for i := range visor.LED { 130 | if i == pos { 131 | visor.LED[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00, A: 0x77} 132 | } else { 133 | visor.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x77} 134 | } 135 | } 136 | 137 | visor.Show() 138 | } 139 | -------------------------------------------------------------------------------- /examples/blink-all/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | func main() { 10 | led := gopherbot.StatusLED() 11 | antenna := gopherbot.Antenna() 12 | visor := gopherbot.Visor() 13 | backpack := gopherbot.Backpack() 14 | 15 | slider := gopherbot.Slider() 16 | 17 | for { 18 | if slider.IsOn() { 19 | led.On() 20 | antenna.On() 21 | visor.Blue() 22 | backpack.Blue() 23 | time.Sleep(500 * time.Millisecond) 24 | 25 | led.Off() 26 | antenna.Off() 27 | visor.Off() 28 | backpack.Off() 29 | time.Sleep(500 * time.Millisecond) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/blink/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | func main() { 10 | antenna := gopherbot.Antenna() 11 | 12 | for { 13 | antenna.On() 14 | time.Sleep(500 * time.Millisecond) 15 | 16 | antenna.Off() 17 | time.Sleep(500 * time.Millisecond) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/demo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenVisor = iota 12 | redVisor 13 | cylonVisor 14 | tiltVisor 15 | xmasVisor 16 | ) 17 | 18 | const ( 19 | forward = iota 20 | backward 21 | ) 22 | 23 | var ( 24 | accel *gopherbot.AccelerometerDevice 25 | visor *gopherbot.VisorDevice 26 | speaker *gopherbot.SpeakerDevice 27 | 28 | pos = 0 29 | ) 30 | 31 | func main() { 32 | accel = gopherbot.Accelerometer() 33 | visor = gopherbot.Visor() 34 | speaker = gopherbot.Speaker() 35 | 36 | antenna := gopherbot.Antenna() 37 | backpack := gopherbot.Backpack() 38 | 39 | left := gopherbot.LeftButton() 40 | right := gopherbot.RightButton() 41 | 42 | mode := redVisor 43 | 44 | go antenna.Blink() 45 | 46 | for { 47 | if right.Pushed() { 48 | mode++ 49 | if mode > xmasVisor { 50 | mode = greenVisor 51 | } 52 | } 53 | 54 | if left.Pushed() { 55 | mode-- 56 | if mode < greenVisor { 57 | mode = xmasVisor 58 | } 59 | } 60 | 61 | switch mode { 62 | case greenVisor: 63 | visor.Green() 64 | if gopherbot.Slider().IsOn() { 65 | backpack.Alternate(color.RGBA{R: 0x00, G: 0xff, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0xff}) 66 | } else { 67 | backpack.Off() 68 | } 69 | case redVisor: 70 | visor.Red() 71 | if gopherbot.Slider().IsOn() { 72 | backpack.Red() 73 | } else { 74 | backpack.Off() 75 | } 76 | case cylonVisor: 77 | visor.Cylon() 78 | if gopherbot.Slider().IsOn() { 79 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 80 | } else { 81 | backpack.Off() 82 | } 83 | case tiltVisor: 84 | tilt() 85 | case xmasVisor: 86 | visor.Xmas() 87 | if gopherbot.Slider().IsOn() { 88 | backpack.Xmas() 89 | } else { 90 | backpack.Off() 91 | } 92 | } 93 | 94 | time.Sleep(200 * time.Millisecond) 95 | } 96 | } 97 | 98 | func tilt() { 99 | x, y, z, _ := accel.ReadAcceleration() 100 | println(x, y, z) 101 | 102 | switch { 103 | case x < 300000 && x > -300000: 104 | switch { 105 | case pos <= gopherbot.VisorLEDCount/2-1: 106 | pos++ 107 | case pos >= gopherbot.VisorLEDCount/2+1: 108 | pos-- 109 | } 110 | case x > 300000: 111 | pos++ 112 | if pos == gopherbot.VisorLEDCount { 113 | pos = gopherbot.VisorLEDCount - 1 114 | speaker.Bleep() 115 | } 116 | case x < -300000: 117 | pos-- 118 | if pos < 0 { 119 | pos = 0 120 | speaker.Bleep() 121 | } 122 | } 123 | 124 | for i := range visor.LED { 125 | if i == pos { 126 | visor.LED[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00, A: 0x77} 127 | } else { 128 | visor.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x77} 129 | } 130 | } 131 | 132 | visor.Show() 133 | } 134 | -------------------------------------------------------------------------------- /examples/findmy/README.md: -------------------------------------------------------------------------------- 1 | # Find My Gopherbot 2 | 3 | Your Gopherbot is now a FindMy beacon. 4 | 5 | Requires CircuitPlayground Bluefruit. 6 | 7 | Uses "Go Haystack" see [https://github.com/hybridgroup/go-haystack](https://github.com/hybridgroup/go-haystack) 8 | 9 | ## Flashing 10 | 11 | ```shell 12 | tinygo flash -target circuitplay-bluefruit -ldflags="-X main.AdvertisingKey='YOURKEYHERE'" ./examples/demo 13 | ``` 14 | -------------------------------------------------------------------------------- /examples/findmy/beacon.go: -------------------------------------------------------------------------------- 1 | //go:build circuitplay_bluefruit 2 | 3 | package main 4 | 5 | import ( 6 | "encoding/base64" 7 | "errors" 8 | "time" 9 | 10 | "github.com/hybridgroup/go-haystack/lib/findmy" 11 | "tinygo.org/x/bluetooth" 12 | ) 13 | 14 | var adapter = bluetooth.DefaultAdapter 15 | 16 | // AdvertisingKey is the public key of the device. Must be base64 encoded. 17 | var AdvertisingKey string 18 | 19 | func initBeacon() { 20 | // wait for USB serial to be available 21 | time.Sleep(2 * time.Second) 22 | 23 | key, err := getKeyData() 24 | if err != nil { 25 | fail("failed to get key data: " + err.Error()) 26 | } 27 | println("key is", AdvertisingKey, "(", len(key), "bytes)") 28 | 29 | opts := bluetooth.AdvertisementOptions{ 30 | AdvertisementType: bluetooth.AdvertisingTypeNonConnInd, 31 | Interval: bluetooth.NewDuration(1285000 * time.Microsecond), // 1285ms 32 | ManufacturerData: []bluetooth.ManufacturerDataElement{findmy.NewData(key)}, 33 | } 34 | 35 | must("enable BLE stack", adapter.Enable()) 36 | 37 | // Set the address to the first 6 bytes of the public key. 38 | adapter.SetRandomAddress(bluetooth.MAC{key[5], key[4], key[3], key[2], key[1], key[0] | 0xC0}) 39 | 40 | println("configure advertising...") 41 | adv := adapter.DefaultAdvertisement() 42 | must("config adv", adv.Configure(opts)) 43 | 44 | println("start advertising...") 45 | must("start adv", adv.Start()) 46 | } 47 | 48 | // getKeyData returns the public key data from the base64 encoded string. 49 | func getKeyData() ([]byte, error) { 50 | val, err := base64.StdEncoding.DecodeString(AdvertisingKey) 51 | if err != nil { 52 | return nil, err 53 | } 54 | if len(val) != 28 { 55 | return nil, errors.New("public key must be 28 bytes long") 56 | } 57 | 58 | return val, nil 59 | } 60 | 61 | // must calls a function and fails if an error occurs. 62 | func must(action string, err error) { 63 | if err != nil { 64 | fail("failed to " + action + ": " + err.Error()) 65 | } 66 | } 67 | 68 | // fail prints a message over and over forever. 69 | func fail(msg string) { 70 | for { 71 | println(msg) 72 | time.Sleep(time.Second) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /examples/findmy/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenVisor = iota 12 | redVisor 13 | cylonVisor 14 | tiltVisor 15 | xmasVisor 16 | ) 17 | 18 | const ( 19 | forward = iota 20 | backward 21 | ) 22 | 23 | var ( 24 | accel *gopherbot.AccelerometerDevice 25 | visor *gopherbot.VisorDevice 26 | speaker *gopherbot.SpeakerDevice 27 | 28 | pos = 0 29 | ) 30 | 31 | func main() { 32 | initBeacon() 33 | 34 | accel = gopherbot.Accelerometer() 35 | visor = gopherbot.Visor() 36 | speaker = gopherbot.Speaker() 37 | 38 | antenna := gopherbot.Antenna() 39 | backpack := gopherbot.Backpack() 40 | 41 | left := gopherbot.LeftButton() 42 | right := gopherbot.RightButton() 43 | 44 | mode := redVisor 45 | 46 | go antenna.Blink() 47 | 48 | for { 49 | if right.Pushed() { 50 | mode++ 51 | if mode > xmasVisor { 52 | mode = greenVisor 53 | } 54 | } 55 | 56 | if left.Pushed() { 57 | mode-- 58 | if mode < greenVisor { 59 | mode = xmasVisor 60 | } 61 | } 62 | 63 | switch mode { 64 | case greenVisor: 65 | visor.Green() 66 | if gopherbot.Slider().IsOn() { 67 | backpack.Alternate(color.RGBA{R: 0x00, G: 0xff, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0xff}) 68 | } else { 69 | backpack.Off() 70 | } 71 | case redVisor: 72 | visor.Red() 73 | if gopherbot.Slider().IsOn() { 74 | backpack.Red() 75 | } else { 76 | backpack.Off() 77 | } 78 | case cylonVisor: 79 | visor.Cylon() 80 | if gopherbot.Slider().IsOn() { 81 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 82 | } else { 83 | backpack.Off() 84 | } 85 | case tiltVisor: 86 | tilt() 87 | case xmasVisor: 88 | visor.Xmas() 89 | if gopherbot.Slider().IsOn() { 90 | backpack.Xmas() 91 | } else { 92 | backpack.Off() 93 | } 94 | } 95 | 96 | time.Sleep(200 * time.Millisecond) 97 | } 98 | } 99 | 100 | func tilt() { 101 | x, y, z, _ := accel.ReadAcceleration() 102 | println(x, y, z) 103 | 104 | switch { 105 | case x < 300000 && x > -300000: 106 | switch { 107 | case pos <= gopherbot.VisorLEDCount/2-1: 108 | pos++ 109 | case pos >= gopherbot.VisorLEDCount/2+1: 110 | pos-- 111 | } 112 | case x > 300000: 113 | pos++ 114 | if pos == gopherbot.VisorLEDCount { 115 | pos = gopherbot.VisorLEDCount - 1 116 | speaker.Bleep() 117 | } 118 | case x < -300000: 119 | pos-- 120 | if pos < 0 { 121 | pos = 0 122 | speaker.Bleep() 123 | } 124 | } 125 | 126 | for i := range visor.LED { 127 | if i == pos { 128 | visor.LED[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00, A: 0x77} 129 | } else { 130 | visor.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x77} 131 | } 132 | } 133 | 134 | visor.Show() 135 | } 136 | -------------------------------------------------------------------------------- /examples/sensors/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | temperature = iota 12 | lightlevel 13 | ) 14 | 15 | const ( 16 | forward = iota 17 | backward 18 | ) 19 | 20 | var ( 21 | thermo *gopherbot.ThermometerDevice 22 | photo *gopherbot.LightMeterDevice 23 | 24 | backpack *gopherbot.BackpackDevice 25 | 26 | pos = 0 27 | dir = 0 28 | ) 29 | 30 | func main() { 31 | backpack = gopherbot.Backpack() 32 | 33 | thermo = gopherbot.Thermometer() 34 | photo = gopherbot.LightMeter() 35 | 36 | left := gopherbot.LeftButton() 37 | right := gopherbot.RightButton() 38 | 39 | mode := temperature 40 | 41 | for { 42 | if right.Pushed() { 43 | mode++ 44 | if mode > lightlevel { 45 | mode = temperature 46 | } 47 | } 48 | 49 | if left.Pushed() { 50 | mode-- 51 | if mode < temperature { 52 | mode = lightlevel 53 | } 54 | } 55 | 56 | switch mode { 57 | case temperature: 58 | showTemperature() 59 | case lightlevel: 60 | showLumens() 61 | } 62 | 63 | time.Sleep(200 * time.Millisecond) 64 | } 65 | } 66 | 67 | func showTemperature() { 68 | temp, _ := thermo.ReadTemperature() 69 | 70 | ts := gopherbot.Rescale(temp, 0, 35000, 0, 255) 71 | println(temp, ts) 72 | 73 | var r, g, b byte 74 | switch { 75 | case temp < 12000: 76 | b = byte(ts) 77 | case temp > 12000 && temp < 25000: 78 | g = byte(ts) 79 | case temp > 25000: 80 | r = byte(ts) 81 | } 82 | backpack.SetColor(color.RGBA{R: r, G: g, B: b}) 83 | } 84 | 85 | func showLumens() { 86 | lumens := photo.Get() 87 | 88 | lvl := gopherbot.Rescale(int32(lumens), 0, 35000, 0, 255) 89 | println(lumens, lvl) 90 | 91 | var r, g, b byte 92 | switch { 93 | case lumens < 12000: 94 | b = byte(lvl) 95 | case lumens > 12000 && lumens < 25000: 96 | g = byte(lvl) 97 | case lumens > 25000: 98 | r = byte(lvl) 99 | } 100 | backpack.SetColor(color.RGBA{R: r, G: g, B: b}) 101 | } 102 | -------------------------------------------------------------------------------- /examples/speaker/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | func main() { 10 | speaker := gopherbot.Speaker() 11 | 12 | left := gopherbot.LeftButton() 13 | right := gopherbot.RightButton() 14 | 15 | for { 16 | if right.Pushed() { 17 | speaker.Bleep() 18 | } 19 | 20 | if left.Pushed() { 21 | speaker.Bloop() 22 | } 23 | 24 | time.Sleep(200 * time.Millisecond) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/visor/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | const ( 10 | greenVisor = iota 11 | redVisor 12 | cylonVisor 13 | xmasVisor 14 | ) 15 | 16 | const ( 17 | forward = iota 18 | backward 19 | ) 20 | 21 | func main() { 22 | visor := gopherbot.Visor() 23 | 24 | left := gopherbot.LeftButton() 25 | right := gopherbot.RightButton() 26 | 27 | mode := redVisor 28 | 29 | for { 30 | if right.Pushed() { 31 | mode++ 32 | if mode > xmasVisor { 33 | mode = greenVisor 34 | } 35 | } 36 | 37 | if left.Pushed() { 38 | mode-- 39 | if mode < greenVisor { 40 | mode = xmasVisor 41 | } 42 | } 43 | 44 | switch mode { 45 | case greenVisor: 46 | visor.Green() 47 | case redVisor: 48 | visor.Red() 49 | case cylonVisor: 50 | visor.Cylon() 51 | case xmasVisor: 52 | visor.Xmas() 53 | } 54 | 55 | time.Sleep(200 * time.Millisecond) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/hybridgroup/gopherbot 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/hybridgroup/go-haystack v0.0.0-20250113144610-93e5f489aab9 7 | tinygo.org/x/bluetooth v0.10.1-0.20250112143431-f36a7a606bfb 8 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea 9 | ) 10 | 11 | require ( 12 | github.com/go-ole/go-ole v1.2.6 // indirect 13 | github.com/godbus/dbus/v5 v5.1.0 // indirect 14 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 15 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b // indirect 16 | github.com/sirupsen/logrus v1.9.3 // indirect 17 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5 // indirect 18 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef // indirect 19 | github.com/tinygo-org/cbgo v0.0.4 // indirect 20 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 // indirect 21 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 // indirect 22 | golang.org/x/sys v0.11.0 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 5 | github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 6 | github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= 7 | github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 8 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= 9 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= 10 | github.com/hybridgroup/go-haystack v0.0.0-20250113144610-93e5f489aab9 h1:Xi8Q9ifILFEjgtYUpTBNOCDY92e23iC66ejazxlybqg= 11 | github.com/hybridgroup/go-haystack v0.0.0-20250113144610-93e5f489aab9/go.mod h1:DvH8VgHcL/L57TkU2JjwjZSIb+CBD5kD4H2ijx/9f7w= 12 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b h1:du3zG5fd8snsFN6RBoLA7fpaYV9ZQIsyH9snlk2Zvik= 16 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= 17 | github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= 18 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 19 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 20 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5 h1:arwJFX1x5zq+wUp5ADGgudhMQEXKNMQOmTh+yYgkwzw= 21 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5/go.mod h1:1Otjk6PRhfzfcVHeWMEeku/VntFqWghUwuSQyivb2vE= 22 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef h1:phH95I9wANjTYw6bSYLZDQfNvao+HqYDom8owbNa0P4= 23 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef/go.mod h1:oCVCNGCHMKoBj97Zp9znLbQ1nHxpkmOY9X+UAGzOxc8= 24 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 25 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 26 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 27 | github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= 28 | github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 29 | github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU= 30 | github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk= 31 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 h1:/DyaXDEWMqoVUVEJVJIlNk1bXTbFs8s3Q4GdPInSKTQ= 32 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899/go.mod h1:LU7Dw00NJ+N86QkeTGjMLNkYcEYMor6wTDpTCu0EaH8= 33 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw= 34 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= 35 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 36 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 37 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 38 | golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= 39 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 40 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 41 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 42 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 43 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 44 | tinygo.org/x/bluetooth v0.10.1-0.20250112143431-f36a7a606bfb h1:OD85S4a/3+lVCSPa4DsxSoCqxBxaHJluUA1IR66yzEQ= 45 | tinygo.org/x/bluetooth v0.10.1-0.20250112143431-f36a7a606bfb/go.mod h1:XLRopLvxWmIbofpZSXc7BGGCpgFOV5lrZ1i/DQN0BCw= 46 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea h1:1ORaETzQPC3iCAda5TW35HiqbSji3JPu8cKZBfyG7P8= 47 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea/go.mod h1:q/mU8G/wz821p8xXqbkBACOlmZFDHXd//DnYnCW+dDQ= 48 | -------------------------------------------------------------------------------- /gopherbot.go: -------------------------------------------------------------------------------- 1 | // Package gopherbot is the TinyGo code for the Gopherbot programmable robotic plushie. 2 | package gopherbot 3 | 4 | import "machine" 5 | 6 | const ( 7 | // BackpackLEDCount is how many WS2812 LEDs are on the backpack, aka 8 | // the Circuit Playground Express. 9 | BackpackLEDCount = 10 10 | 11 | // VisorLEDCount is how many WS2812 LEDs are on the helmet visor. 12 | VisorLEDCount = 12 13 | ) 14 | 15 | var ( 16 | adcInitComplete = false 17 | i2cInitComplete = false 18 | ) 19 | 20 | // EnsureADCInit makes sure that the Gopherbot ADC has been initialized, but 21 | // is only initialized once. 22 | func EnsureADCInit() { 23 | if !adcInitComplete { 24 | machine.InitADC() 25 | adcInitComplete = true 26 | } 27 | } 28 | 29 | // EnsureI2CInit makes sure that the Gopherbot I2C has been initialized, but 30 | // is only initialized once. 31 | func EnsureI2CInit() { 32 | if !i2cInitComplete { 33 | machine.I2C1.Configure(machine.I2CConfig{SCL: machine.SCL1_PIN, SDA: machine.SDA1_PIN}) 34 | i2cInitComplete = true 35 | } 36 | } 37 | 38 | // Rescale performs a direct linear rescaling of an integer from one scale to another. 39 | // 40 | // For example: 41 | // 42 | // val := gopherbot.Rescale(25, 0, 100, 0, 10) 43 | // 44 | // This re-scales the number 25 from a scale that ranges from 0-100, 45 | // to a scale that ranges from 0-10. 46 | func Rescale(input, fromMin, fromMax, toMin, toMax int32) int32 { 47 | return (input-fromMin)*(toMax-toMin)/(fromMax-fromMin) + toMin 48 | } 49 | -------------------------------------------------------------------------------- /learn/README.md: -------------------------------------------------------------------------------- 1 | # Learning TinyGo Using Gopherbot 2 | 3 | Here are a series of activities to learn about TinyGo by using Gopherbot. 4 | 5 | [![GoDoc](https://godoc.org/github.com/hybridgroup/gopherbot?status.svg)](https://godoc.org/github.com/hybridgroup/gopherbot) 6 | 7 | ## Installation 8 | 9 | If you have not done it yet, follow the installation instructions here: 10 | 11 | https://github.com/hybridgroup/gopherbot#installation 12 | 13 | ## Code 14 | 15 | ### step0.go - Built-in LED 16 | 17 | This tests that you can compile and flash your Gopherbot with TinyGo code, by blinking the built-in LED. 18 | 19 | - Plug your Circuit Playground Express into your computer's USB port. 20 | - Build your TinyGo program to the board in `.uf2` format using this command: 21 | 22 | ```shell 23 | tinygo flash -target=gopherbot ./learn/step0/main.go 24 | ``` 25 | 26 | - The Circuit Playground Express board should restart and then begin running your program. This program just causes the small LED labelled "D13" on the Circuit Playground Express board to start blinking on and off. 27 | 28 | ### step1.go - LED, Button A 29 | 30 | Now, instead of just using the low-level TinyGo functions, we are going to use the more advanced "Gopherbot" API to program our furrie robotic friend. Gopherbot has more pre-defined behaviors, but of course all of these are built on top of the lower-level TinyGo "machine" API. 31 | 32 | Want to see complete documentation of the Gopherbot API? Check out our GoDocs here at: 33 | https://godoc.org/github.com/hybridgroup/gopherbot 34 | 35 | First thing we are going to do is to program the left button on the backpack. Let's make it so when the button is pressed, the small built-in LED on the board turns on. Also, the code will make it so that when the button is released that the LED turns off. 36 | 37 | ```shell 38 | tinygo flash -target=gopherbot ./learn/step1/main.go 39 | ``` 40 | 41 | ### step2.go - LED, Button A, Button B 42 | 43 | Next, let's do the same thing for the right button that we did for the left one. When the button is pressed, the small built-in LED on the board turns on. Also, the code will make it so that when the button is released that the LED turns off. 44 | 45 | ```shell 46 | tinygo flash -target=gopherbot ./learn/step2/main.go 47 | ``` 48 | 49 | ### step3.go - LED, Button A, Button B, Backpack LEDs 50 | 51 | Now we will get brightly colored, by adding the ring of Red Green Blue (RGB) LEDs that are on the Circuit Playground Express board on the `Backpack`. 52 | 53 | The Gopherbot `Backpack` has several built-in functions for these LEDs to set colors and patterns. We will add three of these color settings to the program. 54 | 55 | We will also use the buttons to select which of the `Backpack` colors to display. Pushing the right or left button will scroll thru these three color presets. 56 | 57 | ```shell 58 | tinygo flash -target=gopherbot ./learn/step3/main.go 59 | ``` 60 | 61 | ### step4.go - LED, Button A, Button B, Backpack LEDs, Slider switch 62 | 63 | The RGB LEDs are really bright! Let's add the ability to turn them on and off using the built-in slider switch. 64 | 65 | ```shell 66 | tinygo flash -target=gopherbot ./learn/step4/main.go 67 | ``` 68 | 69 | ### step5.go - LED, Button A, Button B, Backpack LEDs, Slider switch, Antenna LED 70 | 71 | Now we need to get the LED on the end of the `Antenna` blinking. We can do this so that it automatically blinks over and over by using a goroutine to call the `Antenna.Blink()` function. 72 | 73 | ```shell 74 | tinygo flash -target=gopherbot ./learn/step5/main.go 75 | ``` 76 | 77 | ### step6.go - LED, Button A, Button B, Backpack LEDs, Slider switch, Antenna LED, Visor LEDs 78 | 79 | Time to fully activate Gopherbot by controlling the RGB LEDs that are in the helmet's `Visor`. 80 | 81 | Similarly to the `Backpack` does, the `Visor` has several built-in functions for the LEDs to set colors and patterns. We will add three of these color settings to the program. 82 | 83 | We will also use the buttons to select which of the `Visor` colors to display. Pushing the right or left button will scroll thru these three color presets at the same time that it chooses the presets for the `Backpack`. 84 | 85 | One difference will be that we will program Gopherbot so that the `Visor` stays on regardless of state of the `Slider` switch. 86 | 87 | ```shell 88 | tinygo flash -target=gopherbot ./learn/step6/main.go 89 | ``` 90 | 91 | ### step7.go - LED, Button A, Button B, Backpack LEDs, Slider switch, Antenna LED, Visor LEDs, Thermistor 92 | 93 | Now that we have all the LEDs working all at the same time, let's explore one of the sensors that is built-in. The Circuit Playground Express board has an onboard `Thermometer` which is actually a kind of analog temperature sensor known as a thermistor. 94 | 95 | We will add to our program an additional `mode` which will read the current temperature, and then modify the `Visor` depending on the reading from the `Thermometer`. 96 | 97 | ```shell 98 | tinygo flash -target=gopherbot ./learn/step7/main.go 99 | ``` 100 | 101 | ### step8.go - LED, Button A, Button B, Backpack LEDs, Slider switch, Antenna LED, Visor LEDs, Thermistor, Accelerometer 102 | 103 | Let try another of the built-in sensors on the Circuit Playground Express board. It has an onboard `Accelerometer` which is a sensor that can detect motion on any of 3 different axes. 104 | 105 | We will add to our program another `mode` which will read the `Accelerometer`, and then based on the tilt position of the Gopherbot, modify the `Visor` to make it act like a "level". 106 | 107 | ```shell 108 | tinygo flash -target=gopherbot ./learn/step8/main.go 109 | ``` 110 | 111 | ### step9.go - LED, Button A, Button B, Backpack LEDs, Slider switch, Antenna LED, Visor LEDs, Thermistor, Accelerometer, Buzzer 112 | 113 | Out final modification to the program will add the built-in `Speaker` to make a bleeping sound when the `tilt()` function detects that the Gopherbot is laying entirely on its side. 114 | 115 | ```shell 116 | tinygo flash -target=gopherbot ./learn/step9/main.go 117 | ``` 118 | -------------------------------------------------------------------------------- /learn/step0/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "machine" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | led := machine.LED 10 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 11 | 12 | for { 13 | led.High() 14 | time.Sleep(time.Millisecond * 500) 15 | 16 | led.Low() 17 | time.Sleep(time.Millisecond * 500) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /learn/step1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | func main() { 10 | left := gopherbot.LeftButton() 11 | led := gopherbot.StatusLED() 12 | 13 | for { 14 | if left.Pushed() { 15 | led.On() 16 | } else { 17 | led.Off() 18 | } 19 | 20 | time.Sleep(100 * time.Millisecond) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /learn/step2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/hybridgroup/gopherbot" 7 | ) 8 | 9 | func main() { 10 | left := gopherbot.LeftButton() 11 | right := gopherbot.RightButton() 12 | 13 | led := gopherbot.StatusLED() 14 | 15 | for { 16 | statusOn := false 17 | 18 | if left.Pushed() { 19 | statusOn = true 20 | } 21 | 22 | if right.Pushed() { 23 | statusOn = true 24 | } 25 | 26 | if statusOn { 27 | led.On() 28 | } else { 29 | led.Off() 30 | } 31 | 32 | time.Sleep(100 * time.Millisecond) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /learn/step3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | ) 15 | 16 | const ( 17 | forward = iota 18 | backward 19 | ) 20 | 21 | func main() { 22 | left := gopherbot.LeftButton() 23 | right := gopherbot.RightButton() 24 | 25 | led := gopherbot.StatusLED() 26 | backpack := gopherbot.Backpack() 27 | 28 | mode := greenJet 29 | 30 | for { 31 | statusOn := false 32 | 33 | if left.Pushed() { 34 | statusOn = true 35 | mode-- 36 | if mode < greenJet { 37 | mode = redRotate 38 | } 39 | } 40 | 41 | if right.Pushed() { 42 | statusOn = true 43 | mode++ 44 | if mode > redRotate { 45 | mode = greenJet 46 | } 47 | } 48 | 49 | if statusOn { 50 | led.On() 51 | } else { 52 | led.Off() 53 | } 54 | 55 | switch mode { 56 | case greenJet: 57 | backpack.Green() 58 | case redJet: 59 | backpack.Red() 60 | case redRotate: 61 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 62 | } 63 | 64 | time.Sleep(100 * time.Millisecond) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /learn/step4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | ) 15 | 16 | const ( 17 | forward = iota 18 | backward 19 | ) 20 | 21 | func main() { 22 | left := gopherbot.LeftButton() 23 | right := gopherbot.RightButton() 24 | slider := gopherbot.Slider() 25 | 26 | led := gopherbot.StatusLED() 27 | backpack := gopherbot.Backpack() 28 | 29 | mode := greenJet 30 | 31 | for { 32 | statusOn := false 33 | 34 | if left.Pushed() { 35 | statusOn = true 36 | mode-- 37 | if mode < greenJet { 38 | mode = redRotate 39 | } 40 | } 41 | 42 | if right.Pushed() { 43 | statusOn = true 44 | mode++ 45 | if mode > redRotate { 46 | mode = greenJet 47 | } 48 | } 49 | 50 | if statusOn { 51 | led.On() 52 | } else { 53 | led.Off() 54 | } 55 | 56 | if slider.IsOn() { 57 | switch mode { 58 | case greenJet: 59 | backpack.Green() 60 | case redJet: 61 | backpack.Red() 62 | case redRotate: 63 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 64 | } 65 | } else { 66 | backpack.Off() 67 | } 68 | 69 | time.Sleep(100 * time.Millisecond) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /learn/step5/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | ) 15 | 16 | const ( 17 | forward = iota 18 | backward 19 | ) 20 | 21 | func main() { 22 | left := gopherbot.LeftButton() 23 | right := gopherbot.RightButton() 24 | slider := gopherbot.Slider() 25 | 26 | led := gopherbot.StatusLED() 27 | backpack := gopherbot.Backpack() 28 | antenna := gopherbot.Antenna() 29 | 30 | mode := greenJet 31 | 32 | go antenna.Blink() 33 | 34 | for { 35 | statusOn := false 36 | 37 | if left.Pushed() { 38 | statusOn = true 39 | mode-- 40 | if mode < greenJet { 41 | mode = redRotate 42 | } 43 | } 44 | 45 | if right.Pushed() { 46 | statusOn = true 47 | mode++ 48 | if mode > redRotate { 49 | mode = greenJet 50 | } 51 | } 52 | 53 | if statusOn { 54 | led.On() 55 | } else { 56 | led.Off() 57 | } 58 | 59 | if slider.IsOn() { 60 | switch mode { 61 | case greenJet: 62 | backpack.Green() 63 | case redJet: 64 | backpack.Red() 65 | case redRotate: 66 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 67 | } 68 | } else { 69 | backpack.Off() 70 | } 71 | 72 | time.Sleep(100 * time.Millisecond) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /learn/step6/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | ) 15 | 16 | const ( 17 | forward = iota 18 | backward 19 | ) 20 | 21 | var ( 22 | visor *gopherbot.VisorDevice 23 | ) 24 | 25 | func main() { 26 | left := gopherbot.LeftButton() 27 | right := gopherbot.RightButton() 28 | slider := gopherbot.Slider() 29 | 30 | led := gopherbot.StatusLED() 31 | backpack := gopherbot.Backpack() 32 | antenna := gopherbot.Antenna() 33 | 34 | visor = gopherbot.Visor() 35 | 36 | mode := greenJet 37 | 38 | go antenna.Blink() 39 | 40 | for { 41 | statusOn := false 42 | 43 | if left.Pushed() { 44 | statusOn = true 45 | mode-- 46 | if mode < greenJet { 47 | mode = redRotate 48 | } 49 | } 50 | 51 | if right.Pushed() { 52 | statusOn = true 53 | mode++ 54 | if mode > redRotate { 55 | mode = greenJet 56 | } 57 | } 58 | 59 | if statusOn { 60 | led.On() 61 | } else { 62 | led.Off() 63 | } 64 | 65 | switch mode { 66 | case greenJet: 67 | visor.Green() 68 | case redJet: 69 | visor.Red() 70 | case redRotate: 71 | visor.Cylon() 72 | } 73 | 74 | if slider.IsOn() { 75 | switch mode { 76 | case greenJet: 77 | backpack.Green() 78 | case redJet: 79 | backpack.Red() 80 | case redRotate: 81 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 82 | } 83 | } else { 84 | backpack.Off() 85 | } 86 | 87 | time.Sleep(100 * time.Millisecond) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /learn/step7/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | roomTemperature 15 | ) 16 | 17 | const ( 18 | forward = iota 19 | backward 20 | ) 21 | 22 | var ( 23 | visor *gopherbot.VisorDevice 24 | thermo *gopherbot.ThermometerDevice 25 | ) 26 | 27 | func main() { 28 | left := gopherbot.LeftButton() 29 | right := gopherbot.RightButton() 30 | slider := gopherbot.Slider() 31 | 32 | led := gopherbot.StatusLED() 33 | backpack := gopherbot.Backpack() 34 | antenna := gopherbot.Antenna() 35 | 36 | visor = gopherbot.Visor() 37 | thermo = gopherbot.Thermometer() 38 | 39 | mode := roomTemperature 40 | 41 | go antenna.Blink() 42 | 43 | for { 44 | statusOn := false 45 | 46 | if left.Pushed() { 47 | statusOn = true 48 | mode-- 49 | if mode < greenJet { 50 | mode = roomTemperature 51 | } 52 | } 53 | 54 | if right.Pushed() { 55 | statusOn = true 56 | mode++ 57 | if mode > roomTemperature { 58 | mode = greenJet 59 | } 60 | } 61 | 62 | if statusOn { 63 | led.On() 64 | } else { 65 | led.Off() 66 | } 67 | 68 | switch mode { 69 | case greenJet: 70 | visor.Green() 71 | case redJet: 72 | visor.Red() 73 | case redRotate: 74 | visor.Cylon() 75 | case roomTemperature: 76 | showTemperature() 77 | } 78 | 79 | if slider.IsOn() { 80 | switch mode { 81 | case greenJet: 82 | backpack.Green() 83 | case redJet: 84 | backpack.Red() 85 | case redRotate: 86 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 87 | case roomTemperature: 88 | backpack.Off() 89 | } 90 | } else { 91 | backpack.Off() 92 | } 93 | 94 | time.Sleep(100 * time.Millisecond) 95 | } 96 | } 97 | 98 | func showTemperature() { 99 | temp, _ := thermo.ReadTemperature() 100 | ts := gopherbot.Rescale(temp, 0, 35000, 0, 255) 101 | var c color.RGBA 102 | 103 | switch { 104 | case temp < 20000: 105 | c = color.RGBA{R: 0x00, G: 0x00, B: byte(ts)} 106 | case temp < 23000: 107 | c = color.RGBA{R: 0x00, G: byte(ts), B: byte(ts)} 108 | case temp < 26000: 109 | c = color.RGBA{R: 0x00, G: byte(ts), B: 0x00} 110 | case temp < 29000: 111 | c = color.RGBA{R: byte(ts), G: byte(ts), B: 0x00} 112 | default: 113 | c = color.RGBA{R: byte(ts), G: 0x00, B: 0x00} 114 | } 115 | 116 | println(temp, ts) 117 | visor.Alternate(c, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 118 | } 119 | -------------------------------------------------------------------------------- /learn/step8/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | roomTemperature 15 | tiltVisor 16 | ) 17 | 18 | const ( 19 | forward = iota 20 | backward 21 | ) 22 | 23 | var ( 24 | visor *gopherbot.VisorDevice 25 | thermo *gopherbot.ThermometerDevice 26 | accel *gopherbot.AccelerometerDevice 27 | 28 | pos = 0 29 | ) 30 | 31 | func main() { 32 | left := gopherbot.LeftButton() 33 | right := gopherbot.RightButton() 34 | slider := gopherbot.Slider() 35 | 36 | led := gopherbot.StatusLED() 37 | backpack := gopherbot.Backpack() 38 | antenna := gopherbot.Antenna() 39 | 40 | visor = gopherbot.Visor() 41 | thermo = gopherbot.Thermometer() 42 | accel = gopherbot.Accelerometer() 43 | 44 | mode := tiltVisor 45 | 46 | go antenna.Blink() 47 | 48 | for { 49 | statusOn := false 50 | 51 | if left.Pushed() { 52 | statusOn = true 53 | mode-- 54 | if mode < greenJet { 55 | mode = tiltVisor 56 | } 57 | } 58 | 59 | if right.Pushed() { 60 | statusOn = true 61 | mode++ 62 | if mode > tiltVisor { 63 | mode = greenJet 64 | } 65 | } 66 | 67 | if statusOn { 68 | led.On() 69 | } else { 70 | led.Off() 71 | } 72 | 73 | switch mode { 74 | case greenJet: 75 | visor.Green() 76 | case redJet: 77 | visor.Red() 78 | case redRotate: 79 | visor.Cylon() 80 | case roomTemperature: 81 | showTemperature() 82 | case tiltVisor: 83 | tilt() 84 | } 85 | 86 | if slider.IsOn() { 87 | switch mode { 88 | case greenJet: 89 | backpack.Green() 90 | case redJet: 91 | backpack.Red() 92 | case redRotate: 93 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 94 | case roomTemperature: 95 | backpack.Off() 96 | } 97 | } else { 98 | backpack.Off() 99 | } 100 | 101 | time.Sleep(100 * time.Millisecond) 102 | } 103 | } 104 | 105 | func showTemperature() { 106 | temp, _ := thermo.ReadTemperature() 107 | ts := gopherbot.Rescale(temp, 0, 35000, 0, 255) 108 | var c color.RGBA 109 | 110 | switch { 111 | case temp < 20000: 112 | c = color.RGBA{R: 0x00, G: 0x00, B: byte(ts)} 113 | case temp < 23000: 114 | c = color.RGBA{R: 0x00, G: byte(ts), B: byte(ts)} 115 | case temp < 26000: 116 | c = color.RGBA{R: 0x00, G: byte(ts), B: 0x00} 117 | case temp < 29000: 118 | c = color.RGBA{R: byte(ts), G: byte(ts), B: 0x00} 119 | default: 120 | c = color.RGBA{R: byte(ts), G: 0x00, B: 0x00} 121 | } 122 | 123 | println(temp, ts) 124 | visor.Alternate(c, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 125 | } 126 | 127 | func tilt() { 128 | x, y, z, _ := accel.ReadAcceleration() 129 | println(x, y, z) 130 | 131 | switch { 132 | case x < 300000 && x > -300000: 133 | switch { 134 | case pos <= gopherbot.VisorLEDCount/2-1: 135 | pos++ 136 | case pos >= gopherbot.VisorLEDCount/2+1: 137 | pos-- 138 | } 139 | case x > 300000: 140 | pos++ 141 | if pos == gopherbot.VisorLEDCount { 142 | pos = gopherbot.VisorLEDCount - 1 143 | } 144 | case x < -300000: 145 | pos-- 146 | if pos < 0 { 147 | pos = 0 148 | } 149 | } 150 | 151 | for i := range visor.LED { 152 | if i == pos { 153 | visor.LED[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00, A: 0x77} 154 | } else { 155 | visor.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x77} 156 | } 157 | } 158 | 159 | visor.Show() 160 | } 161 | -------------------------------------------------------------------------------- /learn/step9/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image/color" 5 | "time" 6 | 7 | "github.com/hybridgroup/gopherbot" 8 | ) 9 | 10 | const ( 11 | greenJet = iota 12 | redJet 13 | redRotate 14 | roomTemperature 15 | tiltVisor 16 | ) 17 | 18 | const ( 19 | forward = iota 20 | backward 21 | ) 22 | 23 | var ( 24 | visor *gopherbot.VisorDevice 25 | speaker *gopherbot.SpeakerDevice 26 | 27 | thermo *gopherbot.ThermometerDevice 28 | accel *gopherbot.AccelerometerDevice 29 | 30 | pos = 0 31 | ) 32 | 33 | func main() { 34 | left := gopherbot.LeftButton() 35 | right := gopherbot.RightButton() 36 | slider := gopherbot.Slider() 37 | 38 | led := gopherbot.StatusLED() 39 | backpack := gopherbot.Backpack() 40 | antenna := gopherbot.Antenna() 41 | 42 | visor = gopherbot.Visor() 43 | speaker = gopherbot.Speaker() 44 | 45 | thermo = gopherbot.Thermometer() 46 | accel = gopherbot.Accelerometer() 47 | 48 | mode := tiltVisor 49 | 50 | go antenna.Blink() 51 | 52 | for { 53 | statusOn := false 54 | 55 | if left.Pushed() { 56 | statusOn = true 57 | mode-- 58 | if mode < greenJet { 59 | mode = tiltVisor 60 | } 61 | } 62 | 63 | if right.Pushed() { 64 | statusOn = true 65 | mode++ 66 | if mode > tiltVisor { 67 | mode = greenJet 68 | } 69 | } 70 | 71 | if statusOn { 72 | led.On() 73 | } else { 74 | led.Off() 75 | } 76 | 77 | switch mode { 78 | case greenJet: 79 | visor.Green() 80 | case redJet: 81 | visor.Red() 82 | case redRotate: 83 | visor.Cylon() 84 | case roomTemperature: 85 | showTemperature() 86 | case tiltVisor: 87 | tilt() 88 | } 89 | 90 | if slider.IsOn() { 91 | switch mode { 92 | case greenJet: 93 | backpack.Green() 94 | case redJet: 95 | backpack.Red() 96 | case redRotate: 97 | backpack.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 98 | case roomTemperature: 99 | backpack.Off() 100 | } 101 | } else { 102 | backpack.Off() 103 | } 104 | 105 | time.Sleep(100 * time.Millisecond) 106 | } 107 | } 108 | 109 | func showTemperature() { 110 | temp, _ := thermo.ReadTemperature() 111 | ts := gopherbot.Rescale(temp, 0, 35000, 0, 255) 112 | var c color.RGBA 113 | 114 | switch { 115 | case temp < 20000: 116 | c = color.RGBA{R: 0x00, G: 0x00, B: byte(ts)} 117 | case temp < 23000: 118 | c = color.RGBA{R: 0x00, G: byte(ts), B: byte(ts)} 119 | case temp < 26000: 120 | c = color.RGBA{R: 0x00, G: byte(ts), B: 0x00} 121 | case temp < 29000: 122 | c = color.RGBA{R: byte(ts), G: byte(ts), B: 0x00} 123 | default: 124 | c = color.RGBA{R: byte(ts), G: 0x00, B: 0x00} 125 | } 126 | 127 | println(temp, ts) 128 | visor.Alternate(c, color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 129 | } 130 | 131 | func tilt() { 132 | x, y, z, _ := accel.ReadAcceleration() 133 | println(x, y, z) 134 | 135 | switch { 136 | case x < 300000 && x > -300000: 137 | switch { 138 | case pos <= gopherbot.VisorLEDCount/2-1: 139 | pos++ 140 | case pos >= gopherbot.VisorLEDCount/2+1: 141 | pos-- 142 | } 143 | case x > 300000: 144 | pos++ 145 | if pos == gopherbot.VisorLEDCount { 146 | pos = gopherbot.VisorLEDCount - 1 147 | speaker.Bleep() 148 | } 149 | case x < -300000: 150 | pos-- 151 | if pos < 0 { 152 | pos = 0 153 | speaker.Bleep() 154 | } 155 | } 156 | 157 | for i := range visor.LED { 158 | if i == pos { 159 | visor.LED[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00, A: 0x77} 160 | } else { 161 | visor.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x77} 162 | } 163 | } 164 | 165 | visor.Show() 166 | } 167 | -------------------------------------------------------------------------------- /led.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "machine" 5 | "time" 6 | ) 7 | 8 | // LEDDevice controls any of the standard LEDs on Gopherbot. 9 | type LEDDevice struct { 10 | machine.Pin 11 | Speed time.Duration 12 | } 13 | 14 | // StatusLED returns the built-in LED of the Circuit Playground Express. 15 | func StatusLED() *LEDDevice { 16 | led := machine.LED 17 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 18 | 19 | return &LEDDevice{ 20 | Pin: led, 21 | Speed: 500 * time.Millisecond, 22 | } 23 | } 24 | 25 | // On turns on the LED. 26 | func (a *LEDDevice) On() { 27 | a.High() 28 | } 29 | 30 | // Off turns off the LED. 31 | func (a *LEDDevice) Off() { 32 | a.Low() 33 | } 34 | 35 | // Blink starts the LED blinking repeatedly. 36 | func (a *LEDDevice) Blink() { 37 | for { 38 | a.On() 39 | time.Sleep(a.Speed) 40 | 41 | a.Off() 42 | time.Sleep(a.Speed) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sensors.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "machine" 5 | 6 | "tinygo.org/x/drivers/lis3dh" 7 | "tinygo.org/x/drivers/thermistor" 8 | ) 9 | 10 | // AccelerometerDevice controls the Gopherbot built-in LIS3DH. 11 | type AccelerometerDevice struct { 12 | lis3dh.Device 13 | } 14 | 15 | // Accelerometer returns the AccelerometerDevice. 16 | func Accelerometer() *AccelerometerDevice { 17 | EnsureI2CInit() 18 | 19 | accel := lis3dh.New(machine.I2C1) 20 | accel.Address = lis3dh.Address1 // address on the Circuit Playground Express 21 | accel.Configure() 22 | accel.SetRange(lis3dh.RANGE_2_G) 23 | 24 | return &AccelerometerDevice{ 25 | Device: accel, 26 | } 27 | } 28 | 29 | // ThermometerDevice controls the Gopherbot built-in thermistor. 30 | type ThermometerDevice struct { 31 | thermistor.Device 32 | } 33 | 34 | // Thermometer returns the ThermometerDevice. 35 | func Thermometer() *ThermometerDevice { 36 | EnsureADCInit() 37 | 38 | s := thermistor.New(machine.TEMPSENSOR) 39 | s.Configure() 40 | 41 | return &ThermometerDevice{ 42 | Device: s, 43 | } 44 | } 45 | 46 | // LightMeterDevice controls the Gopherbot built-in photoresistor. 47 | type LightMeterDevice struct { 48 | machine.ADC 49 | } 50 | 51 | // LightMeter returns the LightMeterDevice. 52 | func LightMeter() *LightMeterDevice { 53 | EnsureADCInit() 54 | 55 | p := machine.ADC{machine.LIGHTSENSOR} 56 | p.Configure(machine.ADCConfig{}) 57 | 58 | return &LightMeterDevice{ 59 | ADC: p, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /slider.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "machine" 5 | ) 6 | 7 | // SliderDevice is the slider switch. 8 | type SliderDevice struct { 9 | machine.Pin 10 | } 11 | 12 | // IsOn checks to see if the slider is in on position. 13 | func (s *SliderDevice) IsOn() bool { 14 | return !s.Get() 15 | } 16 | 17 | // Slider returns the SliderDevice. 18 | func Slider() *SliderDevice { 19 | slider := machine.SLIDER 20 | slider.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) 21 | 22 | return &SliderDevice{slider} 23 | } 24 | -------------------------------------------------------------------------------- /speaker.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "tinygo.org/x/drivers/buzzer" 5 | ) 6 | 7 | // SpeakerDevice is the Gopherbot speaker. 8 | type SpeakerDevice struct { 9 | buzzer.Device 10 | } 11 | 12 | // Bleep makes a bleep sound using the speaker. 13 | func (s *SpeakerDevice) Bleep() { 14 | s.Tone(buzzer.C3, buzzer.Eighth) 15 | } 16 | 17 | // Bloop makes a bloop sound using the speaker. 18 | func (s *SpeakerDevice) Bloop() { 19 | s.Tone(buzzer.C5, buzzer.Quarter) 20 | } 21 | 22 | // Blip makes a blip sound using the speaker. 23 | func (s *SpeakerDevice) Blip() { 24 | s.Tone(buzzer.C6, buzzer.Eighth/8) 25 | } 26 | -------------------------------------------------------------------------------- /speaker_bluefruit.go: -------------------------------------------------------------------------------- 1 | // +build circuitplay_bluefruit 2 | 3 | package gopherbot 4 | 5 | import ( 6 | "tinygo.org/x/drivers/buzzer" 7 | 8 | "machine" 9 | ) 10 | 11 | // Speaker returns the SpeakerDevice. 12 | func Speaker() *SpeakerDevice { 13 | enable := machine.D11 14 | enable.Configure(machine.PinConfig{Mode: machine.PinOutput}) 15 | enable.Set(true) 16 | 17 | speaker := machine.D12 18 | speaker.Configure(machine.PinConfig{Mode: machine.PinOutput}) 19 | 20 | bzr := buzzer.New(speaker) 21 | return &SpeakerDevice{bzr} 22 | } 23 | -------------------------------------------------------------------------------- /speaker_express.go: -------------------------------------------------------------------------------- 1 | // +build circuitplay_express 2 | 3 | package gopherbot 4 | 5 | import ( 6 | "machine" 7 | 8 | "tinygo.org/x/drivers/buzzer" 9 | ) 10 | 11 | // Speaker returns the SpeakerDevice. 12 | func Speaker() *SpeakerDevice { 13 | enable := machine.PA30 14 | enable.Configure(machine.PinConfig{Mode: machine.PinOutput}) 15 | enable.Set(true) 16 | 17 | speaker := machine.A0 18 | speaker.Configure(machine.PinConfig{Mode: machine.PinOutput}) 19 | 20 | bzr := buzzer.New(speaker) 21 | return &SpeakerDevice{bzr} 22 | } 23 | -------------------------------------------------------------------------------- /visor.go: -------------------------------------------------------------------------------- 1 | package gopherbot 2 | 3 | import ( 4 | "image/color" 5 | "machine" 6 | 7 | "tinygo.org/x/drivers/ws2812" 8 | ) 9 | 10 | // VisorDevice controls the Gopherbot Visor Neopixel LED. 11 | type VisorDevice struct { 12 | ws2812.Device 13 | LED []color.RGBA 14 | alt bool 15 | forward bool 16 | pos int 17 | } 18 | 19 | // Visor returns a new VisorDevice to control Gopherbot Visor. 20 | func Visor() *VisorDevice { 21 | neo := machine.A3 22 | neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) 23 | v := ws2812.New(neo) 24 | 25 | return &VisorDevice{ 26 | Device: v, 27 | LED: make([]color.RGBA, VisorLEDCount), 28 | } 29 | } 30 | 31 | // Show sets the visor to display the current LED array state. 32 | func (v *VisorDevice) Show() { 33 | v.WriteColors(v.LED) 34 | } 35 | 36 | // Off turns off all the LEDs. 37 | func (v *VisorDevice) Off() { 38 | v.Clear() 39 | } 40 | 41 | // SetColor sets the Visor LEDs to a single color. 42 | func (v *VisorDevice) SetColor(color color.RGBA) { 43 | for i := range v.LED { 44 | v.LED[i] = color 45 | } 46 | 47 | v.Show() 48 | } 49 | 50 | // Clear clears the visor. 51 | func (v *VisorDevice) Clear() { 52 | v.SetColor(color.RGBA{R: 0x00, G: 0x00, B: 0x00}) 53 | } 54 | 55 | // Red turns all of the Visor LEDs red. 56 | func (v *VisorDevice) Red() { 57 | v.SetColor(color.RGBA{R: 0xff, G: 0x00, B: 0x00}) 58 | } 59 | 60 | // Green turns all of the Visor LEDs green. 61 | func (v *VisorDevice) Green() { 62 | v.SetColor(color.RGBA{R: 0x00, G: 0xff, B: 0x00}) 63 | } 64 | 65 | // Blue turns all of the Visor LEDs blue. 66 | func (v *VisorDevice) Blue() { 67 | v.SetColor(color.RGBA{R: 0x00, G: 0x00, B: 0xff}) 68 | } 69 | 70 | // Alternate the 2 colors. 71 | func (v *VisorDevice) Alternate(color1, color2 color.RGBA) { 72 | v.alt = !v.alt 73 | for i := range v.LED { 74 | v.alt = !v.alt 75 | if v.alt { 76 | v.LED[i] = color1 77 | } else { 78 | v.LED[i] = color2 79 | } 80 | } 81 | 82 | v.Show() 83 | } 84 | 85 | // Xmas light style 86 | func (v *VisorDevice) Xmas() { 87 | v.Alternate(color.RGBA{R: 0xff, G: 0x00, B: 0x00}, color.RGBA{R: 0x00, G: 0xff, B: 0x00}) 88 | } 89 | 90 | // Cylon visor mode. 91 | func (v *VisorDevice) Cylon() { 92 | if v.forward { 93 | v.pos += 2 94 | if v.pos >= VisorLEDCount { 95 | v.pos = VisorLEDCount - 2 96 | v.forward = false 97 | } 98 | } else { 99 | v.pos -= 2 100 | if v.pos < 0 { 101 | v.pos = 0 102 | v.forward = true 103 | } 104 | } 105 | 106 | for i := 0; i < VisorLEDCount; i += 2 { 107 | if i == v.pos { 108 | v.LED[i] = color.RGBA{R: 0xff, G: 0x00, B: 0x00} 109 | v.LED[i+1] = color.RGBA{R: 0xff, G: 0x00, B: 0x00} 110 | } else { 111 | v.LED[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00} 112 | v.LED[i+1] = color.RGBA{R: 0x00, G: 0x00, B: 0x00} 113 | } 114 | } 115 | 116 | v.Show() 117 | } 118 | --------------------------------------------------------------------------------