-
Notifications
You must be signed in to change notification settings - Fork 16
Many updates, new functions, flow control, simplified examples #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a083973
working SSL, a little more durable parsing of responses
ladyada 134e075
added user agent, flow control, status checkin. make example less wordy
ladyada 979b6ba
added user agent, flow control, status checkin. make example less wordy
ladyada 93adc84
don't allocate a new buffer for every +IPD, they're about 1500 bytes max
ladyada ae04966
big ~20kb buffer works great with RTS flow control
ladyada 9e62ddf
time!
ladyada 4c6c34f
big shuffle and API rename to let us get closer to ESP-on-MicroPython…
ladyada 99638d0
at some point, having a low level socket interface will be useful!
ladyada f7dbb92
a little more status checking
ladyada 735ec46
allow default (115200) baudrate and optional high speed baudrate. mor…
ladyada 291b5cc
faster conneciton rate for stargazer
ladyada 6630f4c
add ping, redo simple test
ladyada 5d11071
updated to new style
ladyada afdf1d7
final example redone
ladyada 99f47c3
example setting file
ladyada 79b7434
more g0th than github stars
ladyada 4ad29ee
merge and extend the bitcoin/githubstars/skulls demo into one mega de…
ladyada 68e237e
commentin' party
ladyada acebfc1
linted
ladyada 3324ee7
its the lintiest time of year!
ladyada 9953a23
add gamma correct
ladyada 47222c6
requested changes!
ladyada File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
""" | ||
This example will query ThingSpeak channel 1417 "CheerLights" and display the | ||
color on a NeoPixel ring or strip | ||
""" | ||
import gc | ||
import time | ||
import board | ||
import busio | ||
from digitalio import DigitalInOut | ||
from Adafruit_CircuitPython_ESP_ATcontrol import adafruit_espatcontrol | ||
import neopixel | ||
import ujson | ||
import adafruit_fancyled.adafruit_fancyled as fancy | ||
|
||
|
||
|
||
# Get wifi details and more from a settings.py file | ||
try: | ||
from settings import settings | ||
except ImportError: | ||
print("WiFi settings are kept in settings.py, please add them there!") | ||
raise | ||
|
||
# CONFIGURATION | ||
TIME_BETWEEN_QUERY = 10 # in seconds | ||
|
||
# Cheerlights! | ||
DATA_SOURCE = "http://api.thingspeak.com/channels/1417/feeds.json?results=1" | ||
DATA_LOCATION = ["feeds", 0, "field2"] | ||
|
||
uart = busio.UART(board.TX, board.RX, timeout=0.1) | ||
resetpin = DigitalInOut(board.D5) | ||
rtspin = DigitalInOut(board.D9) | ||
|
||
# Create the connection to the co-processor and reset | ||
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, run_baudrate=460800, | ||
reset_pin=resetpin, | ||
rts_pin=rtspin, debug=True) | ||
esp.hard_reset() | ||
|
||
# neopixels | ||
pixels = neopixel.NeoPixel(board.A1, 16, brightness=0.3) | ||
pixels.fill(0) | ||
builtin = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.1) | ||
builtin[0] = 0 | ||
|
||
# we'll save the value in question | ||
last_value = value = None | ||
the_time = None | ||
times = 0 | ||
|
||
def get_value(response, location): | ||
"""Extract a value from a json object, based on the path in 'location'""" | ||
try: | ||
print("Parsing JSON response...", end='') | ||
json = ujson.loads(response) | ||
print("parsed OK!") | ||
for x in location: | ||
json = json[x] | ||
return json | ||
except ValueError: | ||
print("Failed to parse json, retrying") | ||
return None | ||
|
||
while True: | ||
try: | ||
while not esp.is_connected: | ||
builtin[0] = (100, 0, 0) | ||
# settings dictionary must contain 'ssid' and 'password' at a minimum | ||
esp.connect(settings) | ||
builtin[0] = (0, 100, 0) | ||
# great, lets get the data | ||
print("Retrieving data source...", end='') | ||
builtin[0] = (100, 100, 0) | ||
header, body = esp.request_url(DATA_SOURCE) | ||
builtin[0] = (0, 0, 100) | ||
print("Reply is OK!") | ||
except (RuntimeError, adafruit_espatcontrol.OKError) as e: | ||
print("Failed to get data, retrying\n", e) | ||
continue | ||
print('-'*40, "Size: ", len(body)) | ||
print(str(body, 'utf-8')) | ||
print('-'*40) | ||
# For mystery reasons, there's two numbers before and after the json data | ||
lines = body.split(b'\r\n') # so split into lines | ||
value = get_value(lines[1], DATA_LOCATION) # an get the middle chunk | ||
builtin[0] = (100, 100, 100) | ||
if not value: | ||
continue | ||
print(times, the_time, "value:", value) | ||
|
||
if last_value != value: | ||
color = int(value[1:],16) | ||
red = color >> 16 & 0xFF | ||
green = color >> 8 & 0xFF | ||
blue = color& 0xFF | ||
gamma_corrected = fancy.gamma_adjust(fancy.CRGB(red, green, blue)).pack() | ||
|
||
pixels.fill(gamma_corrected) | ||
last_value = value | ||
times += 1 | ||
|
||
# normally we wouldn't have to do this, but we get bad fragments | ||
header = body = None | ||
gc.collect() | ||
print(gc.mem_free()) # pylint: disable=no-member | ||
time.sleep(TIME_BETWEEN_QUERY) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
""" | ||
This example will access an API, grab a number like hackaday skulls, github | ||
stars, price of bitcoin, twitter followers... if you can find something that | ||
spits out JSON data, we can display it! | ||
""" | ||
import gc | ||
import time | ||
import board | ||
import busio | ||
from digitalio import DigitalInOut | ||
import audioio | ||
ladyada marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from Adafruit_CircuitPython_ESP_ATcontrol import adafruit_espatcontrol | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should just be import adafruit_espatcontrol for released version |
||
from adafruit_ht16k33 import segments | ||
import neopixel | ||
import ujson | ||
|
||
# Get wifi details and more from a settings.py file | ||
try: | ||
from settings import settings | ||
except ImportError: | ||
print("WiFi settings are kept in settings.py, please add them there!") | ||
raise | ||
|
||
# CONFIGURATION | ||
PLAY_SOUND_ON_CHANGE = False | ||
NEOPIXELS_ON_CHANGE = False | ||
TIME_BETWEEN_QUERY = 60 # in seconds | ||
|
||
# Some data sources and JSON locations to try out | ||
|
||
# Bitcoin value in USD | ||
DATA_SOURCE = "http://api.coindesk.com/v1/bpi/currentprice.json" | ||
DATA_LOCATION = ["bpi", "USD", "rate_float"] | ||
|
||
# Github stars! You can query 1ce a minute without an API key token | ||
#DATA_SOURCE = "https://api.github.com/repos/adafruit/circuitpython" | ||
#if 'github_token' in settings: | ||
# DATA_SOURCE += "?access_token="+settings['github_token'] | ||
#DATA_LOCATION = ["stargazers_count"] | ||
|
||
# Youtube stats | ||
#CHANNEL_ID = "UCpOlOeQjj7EsVnDh3zuCgsA" # this isn't a secret but you have to look it up | ||
#DATA_SOURCE = "https://www.googleapis.com/youtube/v3/channels/?part=statistics&id=" \ | ||
# + CHANNEL_ID +"&key="+settings['youtube_token'] | ||
# try also 'viewCount' or 'videoCount | ||
#DATA_LOCATION = ["items", 0, "statistics", "subscriberCount"] | ||
|
||
|
||
# Subreddit subscribers | ||
#DATA_SOURCE = "https://www.reddit.com/r/circuitpython/about.json" | ||
#DATA_LOCATION = ["data", "subscribers"] | ||
|
||
# Hackaday Skulls (likes), requires an API key | ||
#DATA_SOURCE = "https://api.hackaday.io/v1/projects/1340?api_key="+settings['hackaday_token'] | ||
#DATA_LOCATION = ["skulls"] | ||
|
||
# Twitter followers | ||
#DATA_SOURCE = "https://cdn.syndication.twimg.com/widgets/followbutton/info.json?" + \ | ||
#"screen_names=adafruit" | ||
#DATA_LOCATION = [0, "followers_count"] | ||
|
||
uart = busio.UART(board.TX, board.RX, timeout=0.1) | ||
resetpin = DigitalInOut(board.D5) | ||
rtspin = DigitalInOut(board.D9) | ||
|
||
# Create the connection to the co-processor and reset | ||
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, run_baudrate=921600, | ||
reset_pin=resetpin, | ||
rts_pin=rtspin, debug=True) | ||
esp.hard_reset() | ||
|
||
# Create the I2C interface. | ||
i2c = busio.I2C(board.SCL, board.SDA) | ||
# Attach a 7 segment display and display -'s so we know its not live yet | ||
display = segments.Seg7x4(i2c) | ||
display.print('----') | ||
|
||
# neopixels | ||
if NEOPIXELS_ON_CHANGE: | ||
pixels = neopixel.NeoPixel(board.A1, 16, brightness=0.4, pixel_order=(1, 0, 2, 3)) | ||
pixels.fill(0) | ||
|
||
# music! | ||
if PLAY_SOUND_ON_CHANGE: | ||
wave_file = open("coin.wav", "rb") | ||
wave = audioio.WaveFile(wave_file) | ||
|
||
# we'll save the value in question | ||
last_value = value = None | ||
the_time = None | ||
times = 0 | ||
|
||
def chime_light(): | ||
"""Light up LEDs and play a tune""" | ||
if NEOPIXELS_ON_CHANGE: | ||
for i in range(0, 100, 10): | ||
pixels.fill((i, i, i)) | ||
if PLAY_SOUND_ON_CHANGE: | ||
with audioio.AudioOut(board.A0) as audio: | ||
audio.play(wave) | ||
while audio.playing: | ||
pass | ||
if NEOPIXELS_ON_CHANGE: | ||
for i in range(100, 0, -10): | ||
pixels.fill((i, i, i)) | ||
pixels.fill(0) | ||
|
||
def get_value(response, location): | ||
"""Extract a value from a json object, based on the path in 'location'""" | ||
try: | ||
print("Parsing JSON response...", end='') | ||
json = ujson.loads(response) | ||
print("parsed OK!") | ||
for x in location: | ||
json = json[x] | ||
return json | ||
except ValueError: | ||
print("Failed to parse json, retrying") | ||
return None | ||
|
||
while True: | ||
try: | ||
while not esp.is_connected: | ||
# settings dictionary must contain 'ssid' and 'password' at a minimum | ||
esp.connect(settings) | ||
# great, lets get the data | ||
# get the time | ||
the_time = esp.sntp_time | ||
|
||
print("Retrieving data source...", end='') | ||
header, body = esp.request_url(DATA_SOURCE) | ||
print("Reply is OK!") | ||
except (RuntimeError, adafruit_espatcontrol.OKError) as e: | ||
print("Failed to get data, retrying\n", e) | ||
continue | ||
#print('-'*40, "Size: ", len(body)) | ||
#print(str(body, 'utf-8')) | ||
#print('-'*40) | ||
value = get_value(body, DATA_LOCATION) | ||
if not value: | ||
continue | ||
print(times, the_time, "value:", value) | ||
display.print(int(value)) | ||
|
||
if last_value != value: | ||
chime_light() # animate the neopixels | ||
last_value = value | ||
times += 1 | ||
# normally we wouldn't have to do this, but we get bad fragments | ||
header = body = None | ||
gc.collect() | ||
print(gc.mem_free()) # pylint: disable=no-member | ||
time.sleep(TIME_BETWEEN_QUERY) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# This file is where you keep secret settings, passwords, and tokens! | ||
# If you put them in the code you risk committing that info or sharing it | ||
|
||
settings = { | ||
'ssid' : 'my access point', | ||
'password' : 'hunter2', | ||
ladyada marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'timezone' : -5, # this is offset from UTC | ||
'github_token' : 'abcdefghij0123456789', | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,40 @@ | ||
import time | ||
import board | ||
import busio | ||
from digitalio import DigitalInOut | ||
import adafruit_espatcontrol | ||
|
||
MY_SSID = "my ssid" | ||
MY_PASSWORD = "the password" | ||
# Get wifi details and more from a settings.py file | ||
try: | ||
from settings import settings | ||
except ImportError: | ||
print("WiFi settings are kept in settings.py, please add them there!") | ||
raise | ||
|
||
uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=1) | ||
uart = busio.UART(board.TX, board.RX, timeout=0.1) | ||
resetpin = DigitalInOut(board.D5) | ||
|
||
print("ESP AT commands") | ||
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, reset_pin=resetpin, debug=False) | ||
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, run_baudrate=9600, | ||
reset_pin=resetpin, debug=False) | ||
print("Resetting ESP module") | ||
esp.hard_reset() | ||
|
||
if not esp.soft_reset(): | ||
esp.hard_reset() | ||
esp.soft_reset() | ||
|
||
esp.echo(False) | ||
print("Connected to AT software version ", esp.get_version()) | ||
if esp.mode != esp.MODE_STATION: | ||
esp.mode = esp.MODE_STATION | ||
print("Mode is now", esp.mode) | ||
for ap in esp.scan_APs(): | ||
print(ap) | ||
esp.join_AP(MY_SSID, MY_PASSWORD) | ||
print("My IP Address:", esp.local_ip) | ||
while True: | ||
try: | ||
print("Checking connection...") | ||
while not esp.is_connected: | ||
print("Initializing ESP module") | ||
#print("Scanning for AP's") | ||
#for ap in esp.scan_APs(): | ||
# print(ap) | ||
# settings dictionary must contain 'ssid' and 'password' at a minimum | ||
print("Connecting...") | ||
esp.connect(settings) | ||
print("Connected to AT software version ", esp.version) | ||
print("Pinging 8.8.8.8...", end="") | ||
print(esp.ping("8.8.8.8")) | ||
time.sleep(10) | ||
except (RuntimeError, adafruit_espatcontrol.OKError) as e: | ||
print("Failed to get data, retrying\n", e) | ||
continue |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.