Compare commits

...

38 Commits
0.0.4 ... 0.0.9

Author SHA1 Message Date
Kevin Hester
a91fba763a release 0.0.9 2020-03-03 08:29:37 -08:00
Kevin Hester
28588f6730 send hw version info via protobufs 2020-03-03 08:23:58 -08:00
Kevin Hester
d074218049 no need to stop mesh service during sw update, bug was on the android side 2020-03-03 07:38:56 -08:00
Kevin Hester
1f07d6735b fix a nasty sleep bug: we weren't stopping our old mesh service
so it would kinda keep living (along with the recreated one) when we
come back from sleep.
2020-03-03 07:36:35 -08:00
Kevin Hester
bb0b2e72c8 stop using ino files, visual studio doesn't like them 2020-03-03 07:34:05 -08:00
Kevin Hester
30c717ac2f minor doc updates 2020-03-02 15:31:04 -08:00
Kevin Hester
e01680cd4b Change all repo URLs to be meshtastic... instead of geeksville... 2020-03-02 15:13:33 -08:00
Kevin Hester
4bb308c80c Pull protobufs from submodule instead of a symbolic link Fix #2 2020-03-02 09:57:05 -08:00
Kevin Hester
12a68026e7 clarify release of meshpacket back to pool 2020-03-02 09:02:21 -08:00
Kevin Hester
06449e39c1 Prove to google that we own this domain 2020-03-02 09:02:21 -08:00
Kevin Hester
cc6a8c8430 Merge pull request #12 from claesg/master
Updated the README.md with a new radio: TTGO LORA32
2020-03-01 16:25:51 -08:00
claes
9aedec2c5c Updated the README.md with a new radio: TTGO LORA32 2020-03-01 13:00:15 +01:00
Kevin Hester
2221ddfca2 Add note about a mystery bug following light sleep 2020-02-29 19:06:14 -08:00
Kevin Hester
7dc6264fa7 It helps to spell things correctly... 2020-02-29 19:05:59 -08:00
Kevin Hester
f091a9505a Add a pretty CI badge based on @girtsf work 2020-02-29 19:00:46 -08:00
Kevin Hester
57d5a54099 Merge pull request #6 from girtsf/fix-some-warnings
some minor cleanups
2020-02-29 07:10:50 -08:00
Kevin Hester
045a2031a3 todo updates 2020-02-29 07:08:18 -08:00
Girts Folkmanis
0b8d7768fd some minor cleanups
* Suppress warnings about conflicting library names in platformio.ini by
  explicitly picking the libraries by id that we want.
* fix unused static function warning by making it not static ;)
* declare arduino-fsm as dependency for BluetoothOTA. Hopefully this
  fixes the CI builds?

Tested: `pio run` builds.
2020-02-28 19:26:11 -08:00
Kevin Hester
c41f572cf5 update todo list while sitting in airplane ;-) 2020-02-28 12:36:52 -08:00
geeksville
bf26994d4e add misc hw docs/datasheets 2020-02-27 11:25:27 -08:00
geeksville
30ff67d46a fix CI? 2020-02-26 17:37:08 -08:00
geeksville
65e6d029e0 move CI script 2020-02-26 17:22:37 -08:00
geeksville
31e9d34d1e try github actions for CI builds 2020-02-26 17:20:19 -08:00
geeksville
0a796c4937 get ready for 0.0.6 2020-02-26 14:27:00 -08:00
geeksville
877e312833 allow TBEAMs to provide approx GPS time to Heltec devices 2020-02-26 09:00:53 -08:00
geeksville
cace2f4290 update readme for android release 2020-02-25 11:22:42 -08:00
geeksville
7b348f30ac text messages screen not coming up if screen was already on 2020-02-25 10:29:37 -08:00
geeksville
8893be57df kinda ugly but BLE sw update seems reliable again 2020-02-24 18:09:58 -08:00
geeksville
6b696bfdc5 hw vendor strings must match file names for auto update 2020-02-24 11:21:34 -08:00
geeksville
a3df099f60 until my TBEAM is fixed, leave GPS power on in sleep sometimes 2020-02-24 11:21:08 -08:00
geeksville
0ce1bbb758 expose standard ble sw/hw version characteristics from the updater
We also implement the following standard GATT entries because SW update probably needs them:
+
+ESP_GATT_UUID_SW_VERSION_STR/0x2a28
+ESP_GATT_UUID_MANU_NAME/0x2a29
+ESP_GATT_UUID_HW_VERSION_STR/0x2a27
2020-02-24 10:24:21 -08:00
geeksville
bb808c6c52 fix bluetooth pairing UX. enter full ON state when requested 2020-02-24 10:23:07 -08:00
geeksville
15ea13c286 start machine generating curfirmwareversion 2020-02-24 09:55:02 -08:00
geeksville
b0e0ee6934 begin to track firmware versions in a machine readable way 2020-02-24 09:46:32 -08:00
geeksville
f4791137fd keep latest builds in their own directory - so android build can find them 2020-02-24 09:33:41 -08:00
geeksville
51b53f406e include region code in the BLE HW version string. ie 1.0-US 2020-02-24 09:22:34 -08:00
geeksville
bd0f35ad83 fix encoding of sw version numbers in the BLE device info 2020-02-24 09:12:13 -08:00
geeksville
af5e3a0e02 TODO updates - back to Android app for now 2020-02-24 08:47:02 -08:00
45 changed files with 390 additions and 209 deletions

19
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Continuous Integration
on: push
jobs:
main:
name: Main
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Setup Python
uses: actions/setup-python@master
with:
python-version: 3.x
- name: Install Platform IO
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Build
run: platformio run

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "proto"]
path = proto
url = https://github.com/meshtastic/Meshtastic-protobufs.git

View File

@@ -41,7 +41,8 @@
"utility": "cpp",
"typeinfo": "cpp",
"string": "cpp",
"*.xbm": "cpp"
"*.xbm": "cpp",
"list": "cpp"
},
"cSpell.words": [
"Meshtastic",

View File

@@ -1,6 +1,8 @@
# Meshtastic-esp32
This is the device side code for the [meshtastic.org](https://www.meshtastic.org) project.
![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg)
Meshtastic is a project that lets you use
inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding -
essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other
@@ -16,14 +18,14 @@ This project is currently early-alpha, but if you have questions please join our
This software is 100% open source and developed by a group of hobbyist experimenters. No warranty is provided, if you'd like to improve it - we'd love your help. Please post in the chat.
## Supported hardware
We currently support two brands of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most users should buy the T-Beam and a 18650 battery (total cost less than $35). Make
We currently support three models of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html), [TTGO LORA32](https://www.banggood.com/LILYGO-TTGO-LORA32-868Mhz-SX1276-ESP32-Oled-Display-bluetooth-WIFI-Lora-Development-Module-Board-p-1248652.html?cur_warehouse=UK) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most users should buy the T-Beam and a 18650 battery (total cost less than $35). Make
sure to buy the frequency range which is legal for your country. For the USA, you should buy the 915MHz version. Getting a version that include a screen
is optional, but highly recommended.
See (meshtastic.org) for 3D printable cases.
## Installing the firmware
Prebuilt binaries for the supported radios is available in our [releases](https://github.com/geeksville/Meshtastic-esp32/releases). Your initial installation has to happen over USB from your Mac, Windows or Linux PC. Once our software is installed, all future software updates happen over bluetooth from your phone.
Prebuilt binaries for the supported radios is available in our [releases](https://github.com/meshtastic/Meshtastic-esp32/releases). Your initial installation has to happen over USB from your Mac, Windows or Linux PC. Once our software is installed, all future software updates happen over bluetooth from your phone.
The instructions currently require a few commmand lines, but it should be pretty straightforward. Please post comments on our group chat if you have problems or successes. Steps to install:
@@ -31,7 +33,7 @@ The instructions currently require a few commmand lines, but it should be pretty
2. Install "pip". Pip is the python package manager we use to get the esptool installer app. Instructions [here](https://www.makeuseof.com/tag/install-pip-for-python/).
3. Run "pip install --upgrade esptool" to get esptool installed on your machine
4. Connect your radio to your USB port
5. Confirm that your device is talking to your PC by running "esptool.py chip_id". You should see something like:
5. Confirm that your device is talking to your PC by running "esptool.py chip_id". The Heltec build also works on the TTGO LORA32 radio. You should see something like:
```
mydir$ esptool.py chip_id
esptool.py v2.6
@@ -76,8 +78,11 @@ Hard resetting via RTS pin...
8. Please post a comment on our chat so we know if these instructions worked for you ;-). If you find bugs/have-questions post there also - we will be rapidly iterating over the next few weeks.
## Meshtastic Android app
The source code for the (optional) Meshtastic Android app is [here](https://github.com/geeksville/Meshtastic-Android).
Soon our first alpha release of will be released here:
The source code for the (optional) Meshtastic Android app is [here](https://github.com/meshtastic/Meshtastic-Android).
Alpha test builds are current available by opting into our alpha test group. See (www.meshtastic.org) for instructions.
After our rate of change slows a bit, we will make beta builds available here (without needing to join the alphatest group):
[![Download at https://play.google.com/store/apps/details?id=com.geeksville.mesh](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dgithub%26utm_medium%3Desp32-readme%26utm_campaign%3Dmeshtastic-esp32%2520readme%26anid%3Dadmob&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1)
# Development

111
TODO.md
View File

@@ -1,53 +1,42 @@
# High priority
Items to complete before the first alpha release.
Items to complete soon (next couple of alpha releases).
* have state machine properly enter deep sleep based on loss of mesh and phone comms
* default to enter deep sleep if no LORA received for two hours (indicates user has probably left the meshS)
* if the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs
* text messages are not showing on local screen if screen was on
* The following three items are all the same:
Have state machine properly enter deep sleep based on loss of mesh and phone comms.
Default to enter deep sleep if no LORA received for two hours (indicates user has probably left the mesh).
If the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs
for it (because it will redownload the nodedb when it comes back)
* lower wait_bluetooth_secs to 30 seconds once we have the GPS power on (but GPS in sleep mode) across light sleep. For the time
being I have it set at 2 minutes to ensure enough time for a GPS lock from scratch.
F95::canSleep say no if we are busy receiving a message
* retest BLE software update for both board types
* send note about Adafruit Clue
* send note to the guy who designed the cases
* use gps sleep mode instead of killing its power (to allow fast position when we wake)
* enable fast lock and low power inside the gps chip
* remeasure wake time power draws now that we run CPU down at 80MHz
# AXP192 tasks
* "AXP192 interrupt is not firing, remove this temporary polling of battery state"
* make debug info screen show real data (including battery level & charging) - close corresponding github issue
# Medium priority
Items to complete before the first beta release.
* turn light sleep on aggressively (while lora is on but BLE off)
* sync wake windows to gps time
* good source of battery/signal/gps icons https://materialdesignicons.com/
* investigate changing routing to https://github.com/sudomesh/LoRaLayer2 ?
* check fcc rules on duty cycle. we might not need to freq hop. https://www.sunfiretesting.com/LoRa-FCC-Certification-Guide/
* use fuse bits to store the board type and region. So one load can be used on all boards
* research and implement better mesh algorithm
* the BLE stack is leaking about 200 bytes each time we go to light sleep
* use gps sleep mode instead of killing its power (to allow fast position when we wake)
* leave lora receiver always on
* rx signal measurements -3 marginal, -9 bad, 10 great, -10 means almost unusable. So scale this into % signal strength. preferably as a graph, with an X indicating loss of comms.
* assign every "channel" a random shared 8 bit sync word (per 4.2.13.6 of datasheet) - use that word to filter packets before even checking CRC. This will ensure our CPU will only wake for packets on our "channel"
* Note: we do not do address filtering at the chip level, because we might need to route for the mesh
* Use the Periodic class for both position and user periodic broadcasts
* make debug info screen show real data (including battery level & charging)
* don't forward redundant pings or ping responses to the phone, it just wastes phone battery
* don't treat north as up, instead adjust shown bearings for our guess at the users heading (i.e. subtract one from the other)
* answer to pings (because some other user is looking at our nodeinfo) with our latest location
* show radio and gps signal strength as an image
* only BLE advertise for a short time after the screen is on and button pressed - to save power and prevent people for sniffing for our BT app.
* use https://platformio.org/lib/show/1260/OneButton if necessary
* make an about to sleep screen
* don't send location packets if we haven't moved
* scrub default radio config settings for bandwidth/range/speed
* add basic crypto - http://rweather.github.io/arduinolibs/crypto.html with speck https://www.airspayce.com/mikem/arduino/RadioHead/rf95_encrypted_client_8pde-example.html
* override peekAtMessage so we can see any messages that pass through our node (even if not broadcast)? would that be useful?
* sendToMesh can currently block for a long time, instead have it just queue a packet for a radio freertos thread
* How do avalanche beacons work? Could this do that as well? possibly by using beacon mode feature of the RF95?
* use std::map<NodeInfo*, std::string> in node db
* make a HAM build: yep - that's a great idea. I'll add it to the TODO. should be pretty painless - just a new frequency list, a bool to say 'never do encryption' and use hte callsign as that node's unique id. -from Girts
* add frequency hopping
* add basic crypto - https://github.com/chegewara/esp32-mbedtls-aes-test/blob/master/main/main.c https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation - use ECB at first (though it is shit) because it doesn't require us to send 16 bytes of IV with each packet. Then OFB per example
* add frequency hopping, dependent on the gps time, make the switch moment far from the time anyone is going to be transmitting
* share channel settings over Signal (or qr code) by embedding an an URL which is handled by the MeshUtil app.
* publish update articles on the web
# Pre-beta priority
@@ -55,45 +44,55 @@ Items to complete before the first beta release.
During the beta timeframe the following improvements 'would be nice' (and yeah - I guess some of these items count as features, but it is a hobby project ;-) )
* Figure out why the RF95 ISR is never seeing RH_RF95_VALID_HEADER, so it is not protecting our rx packets from getting stomped on by sends
* use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability
* make an install script to let novices install software on their boards
* fix the frequency error reading in the RF95 RX code (can't do floating point math in an ISR ;-)
* See CustomRF95::send and fix the problem of dropping partially received packets if we want to start sending
* swap out speck for hw-accelerated full AES https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/hwcrypto/aes.h
* use variable length arduino Strings in protobufs (instead of current fixed buffers)
* don't even power on bluetooth until we have some data to send to the android phone. Most of the time we should be sleeping in a lowpower "listening for lora" only mode. Once we have some packets for the phone, then power on bluetooth
until the phone pulls those packets. Ever so often power on bluetooth just so we can see if the phone wants to send some packets. Possibly might need ULP processor to help with this wake process.
* do hibernation mode to get power draw down to 2.5uA https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/
* make sure main cpu is not woken for packets with bad crc or not addressed to this node - do that in the radio hw
* enable fast init inside the gps chip
* triple check fcc compliance
* pick channel center frequency based on name? "dolphin" would hash to 900Mhz, "cat" to 905MHz etc? Or is that too opaque?
* scan to find channels with low background noise?
* share channel settings over Signal (or qr code) by embedding an an URL which is handled by the MeshUtil app.
* pick channel center frequency based on channel name? "dolphin" would hash to 900Mhz, "cat" to 905MHz etc? allows us to hide the concept of channel # from hte user.
* scan to find channels with low background noise? (Use CAD mode of the RF95 to automatically find low noise channels)
* make a no bluetooth configured yet screen - include this screen in the loop if the user hasn't yet paired
* if radio params change fundamentally, discard the nodedb
* reneable the bluetooth battery level service on the T-BEAM, because we can read battery level there
# Spinoff project ideas
* an open source version of https://www.burnair.ch/skynet/
* a paragliding app like http://airwhere.co.uk/
* a version with a solar cell for power, just mounted high to permanently provide routing for nodes in a valley. Someone just pointed me at disaster.radio
* How do avalanche beacons work? Could this do that as well? possibly by using beacon mode feature of the RF95?
* provide generalized (but slow) internet message forwarding servie if one of our nodes has internet connectivity
# Low priority
Items after the first final candidate release.
* Use CAD mode of the RF95 to automatically find low noise channels
* use variable length arduino Strings in protobufs (instead of current fixed buffers)
* use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability
* make an install script to let novices install software on their boards
* use std::map<NodeInfo*, std::string> in node db
* make a HAM build: yep - that's a great idea. I'll add it to the TODO. should be pretty painless - just a new frequency list, a bool to say 'never do encryption' and use hte callsign as that node's unique id. -from Girts
* don't forward redundant pings or ping responses to the phone, it just wastes phone battery
* use https://platformio.org/lib/show/1260/OneButton if necessary
* don't send location packets if we haven't moved
* scrub default radio config settings for bandwidth/range/speed
* answer to pings (because some other user is looking at our nodeinfo) with our latest location (not a stale location)
* show radio and gps signal strength as an image
* only BLE advertise for a short time after the screen is on and button pressed - to save power and prevent people for sniffing for our BT app.
* make mesh aware network timing state machine (sync wake windows to gps time)
* split out the software update utility so other projects can use it. Have the appload specify the URL for downloads.
* read the PMU battery fault indicators and blink/led/warn user on screen
* make a no bluetooth configured yet screen - include this screen in the loop if the user hasn't yet paired
* the AXP debug output says it is trying to charge at 700mA, but the max I've seen is 180mA, so AXP registers probably need to be set to tell them the circuit can only provide 300mAish max. So that the low charge rate kicks in faster and we don't wear out batteries.
* increase the max charging rate a bit for 18650s, currently it limits to 180mA (at 4V). Work backwards from the 500mA USB limit (at 5V) and let the AXP charge at that rate.
* if radio params change fundamentally, discard the nodedb
* discard very old nodedb records (> 1wk)
* using the genpartitions based table doesn't work on TTGO so for now I stay with my old memory map
* We let anyone BLE scan for us (FIXME, perhaps only allow that until we are paired with a phone and configured)
* use two different buildenv flags for ttgo vs lora32. https://docs.platformio.org/en/latest/ide/vscode.html#key-bindings
* sim gps data for testing nodes that don't have hardware
* have android provide position data for nodes that don't have gps
* do debug serial logging to android over bluetooth
* break out my bluetooth OTA software as a seperate library so others can use it
* Heltec LoRa32 has 8MB flash, use a bigger partition table if needed - TTGO is 4MB but has PSRAM
* add a watchdog timer
* fix GPS.zeroOffset calculation it is wrong
* handle millis() rollover in GPS.getTime - otherwise we will break after 50 days
* reneable the bluetooth battery level service on the T-BEAM, because we can read battery level there
* report esp32 device code bugs back to the mothership via android
# Done
@@ -176,3 +175,19 @@ Items after the first final candidate release.
* don't enter NB state if we've recently talked to the phone (to prevent breaking syncing or bluetooth sw update)
* have sw update prevent BLE sleep
* manually delete characteristics/descs
* leave lora receiver always on
* protobufs are sometimes corrupted after sleep!
* stay awake while charging
* check gps battery voltage
* if a position report includes ground truth time and we don't have time yet, set our clock from that. It is better than nothing.
* retest BLE software update for both board types
* report on wikifactory
* send note to the guy who designed the cases
* turn light sleep on aggressively (while lora is on but BLE off)
* Use the Periodic class for both position and user periodic broadcasts
* don't treat north as up, instead adjust shown bearings for our guess at the users heading (i.e. subtract one from the other)
* sendToMesh can currently block for a long time, instead have it just queue a packet for a radio freertos thread
* don't even power on bluetooth until we have some data to send to the android phone. Most of the time we should be sleeping in a lowpower "listening for lora" only mode. Once we have some packets for the phone, then power on bluetooth
until the phone pulls those packets. Ever so often power on bluetooth just so we can see if the phone wants to send some packets. Possibly might need ULP processor to help with this wake process.
* do hibernation mode to get power draw down to 2.5uA https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/
* fix GPS.zeroOffset calculation it is wrong

View File

@@ -2,32 +2,55 @@
set -e
VERSION=0.0.4
source bin/version.sh
COUNTRIES="US EU CN JP"
# COUNTRIES=US
SRCMAP=.pio/build/esp32/output.map
SRCBIN=.pio/build/esp32/firmware.bin
OUTDIR=release/latest
# We keep all old builds (and their map files in the archive dir)
ARCHIVEDIR=release/archive
rm -f $OUTDIR/firmware*
for COUNTRY in $COUNTRIES; do
COMMONOPTS="-DAPP_VERSION=$VERSION -DHW_VERSION_$COUNTRY -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial"
HWVERSTR="1.0-$COUNTRY"
COMMONOPTS="-DAPP_VERSION=$VERSION -DHW_VERSION_$COUNTRY -DHW_VERSION=$HWVERSTR -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial"
export PLATFORMIO_BUILD_FLAGS="-DT_BEAM_V10 $COMMONOPTS"
echo "Building with $PLATFORMIO_BUILD_FLAGS"
rm -f $SRCBIN $SRCMAP
pio run # -v
cp $SRCBIN release/firmware-TBEAM-$COUNTRY-$VERSION.bin
cp $SRCMAP release/firmware-TBEAM-$COUNTRY-$VERSION.map
cp $SRCBIN $OUTDIR/firmware-TBEAM-$COUNTRY-$VERSION.bin
#cp $SRCMAP $ARCHIVEDIR/firmware-TBEAM-$COUNTRY-$VERSION.map
export PLATFORMIO_BUILD_FLAGS="-DHELTEC_LORA32 $COMMONOPTS"
rm -f $SRCBIN $SRCMAP
pio run # -v
cp $SRCBIN release/firmware-HELTEC-$COUNTRY-$VERSION.bin
cp $SRCMAP release/firmware-HELTEC-$COUNTRY-$VERSION.map
cp $SRCBIN $OUTDIR/firmware-HELTEC-$COUNTRY-$VERSION.bin
#cp $SRCMAP $ARCHIVEDIR/firmware-HELTEC-$COUNTRY-$VERSION.map
done
zip release/firmware-$VERSION.zip release/firmware-*-$VERSION.bin
# keep the bins in archive also
cp $OUTDIR/firmware* $ARCHIVEDIR
cat >$OUTDIR/curfirmwareversion.xml <<XML
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is kept in source control because it reflects the last stable
release. It is used by the android app for forcing software updates. Do not edit.
Generated by bin/buildall.sh -->
<resources>
<string name="cur_firmware_version">$VERSION</string>
</resources>
XML
rm -f $ARCHIVEDIR/firmware-$VERSION.zip
zip $ARCHIVEDIR/firmware-$VERSION.zip $OUTDIR/firmware-*-$VERSION.bin
echo BUILT ALL

6
bin/program-release-heltec.sh Executable file
View File

@@ -0,0 +1,6 @@
set -e
source bin/version.sh
esptool.py --baud 921600 write_flash 0x10000 release/firmware-HELTEC-US-$VERSION.bin

View File

@@ -1 +1,6 @@
/home/kevinh/packages/nanopb-0.4.1-linux-x86/generator-bin/protoc --nanopb_out=-v:src -I=../MeshUtil/app/src/main/proto mesh.proto
#!/bin/bash
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.1"
# the nanopb tool seems to require that the .options file be in the current directory!
cd proto
../../nanopb-0.4.1-linux-x86/generator-bin/protoc --nanopb_out=-v:../src -I=../proto mesh.proto

3
bin/version.sh Normal file
View File

@@ -0,0 +1,3 @@
export VERSION=0.0.9

View File

@@ -0,0 +1,9 @@
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.geeksville.mesh",
"sha256_cert_fingerprints":
["D0:05:E7:8B:D2:1B:FA:94:56:1D:6B:90:EB:53:07:1A:74:4F:D9:C2:6F:13:87:6A:D9:17:4F:C2:59:48:02:9D"]
}
}]

View File

@@ -28,35 +28,36 @@ Not all of these features are fully implemented yet - see below. But they shoul
* Open and extensible codebase supporting multiple hardware vendors - no lock in to one vendor
* Communication API for bluetooth devices (such as our Android app) to use the mesh. So if you have some application that needs long range low power networking, this might work for you.
* Eventually (within a couple of months) we should have a modified version of Signal that works with this project.
* Very easy sharing of private secured channels. Just share a special link or QR code with other users and they can join your encrypted mesh
* Very easy sharing of private secured channels. Just share a special link or QR code with friends and they can join your encrypted mesh
This project is currently in early alpha - if you have questions please join our chat [![Join the chat at https://gitter.im/Meshtastic/community](https://badges.gitter.im/Meshtastic/community.svg)](https://gitter.im/Meshtastic/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge).
This software is 100% open source and developed by a group of hobbyist experimenters. No warranty is provided, if you'd like to improve it - we'd love your help. Please post in the [chat](https://gitter.im/Meshtastic/community).
# Update 1
# Updates
* 02/20/2020 - Our first alpha release of the radio software is ready for early users. If you'd like to try it, we'd love your feedback. Click [here](https://github.com/geeksville/Meshtastic-esp32/blob/master/README.md) for instructions.
* 02/25/2020 - 0.0.4 of the Android app is released. This is a very early alpha, see below to join the alpha-testers group.
* 02/23/2020 - 0.0.4 release. Still very bleeding edge but much closer to the final power management, a charged T-BEAM should run for many days with this load. If you'd like to try it, we'd love your feedback. Click [here](https://github.com/meshtastic/Meshtastic-esp32/blob/master/README.md) for instructions.
* 02/20/2020 - Our first alpha release (0.0.3) of the radio software is ready brave early people.
## Meshtastic Android app
Soon our (optional) companion Android application will be released here:
Once out of alpha the companion Android application will be released here:
[![Download at https://play.google.com/store/apps/details?id=com.geeksville.mesh](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dhomepage%26anid%3Dadmob)
If you would like to join our super bleeding-edge alpha test group for this app, we'd love to have you. Three steps:
But if you want the bleeding edge app now, we'd love to have your help testing. Three steps to opt-in to the alpha- test:
1. Join [this Google group](https://groups.google.com/forum/#!forum/meshtastic-alpha-testers) with the account you use in Google Play.
2. Go to this [URL](https://play.google.com/apps/testing/com.geeksville.mesh) to opt-in to the alpha test.
3. If you encounter any problems or have questions, post in our gitter chat and we'll help.
If you'd like to help with development, the source code is [on github](https://github.com/geeksville/Meshtastic-Android).
If you'd like to help with development, the source code is [on github](https://github.com/meshtastic/Meshtastic-Android).
## Supported hardware
We currently support two brands of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most users should buy the T-Beam and a 18650 battery (total cost less than $35). Make
sure to buy the frequency range which is legal for your country. For the USA, you should buy the 915MHz version. Getting a version that include a screen
is optional, but highly recommended.
We currently support two brands of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most people should buy the T-Beam and a 18650 battery (total cost less than $35). Make
sure to buy the frequency range which is legal for your country. For the USA, you should buy the 915MHz version. Getting a version that include a screen is optional, but highly recommended.
Instructions for installing prebuilt firmware can be found [here](https://github.com/geeksville/Meshtastic-esp32/blob/master/README.md).
Instructions for installing prebuilt firmware can be found [here](https://github.com/meshtastic/Meshtastic-esp32/blob/master/README.md).
For a nice TTGO 3D printable case see this [design](https://www.thingiverse.com/thing:3773717) by [bsiege](https://www.thingiverse.com/bsiege).
For a nice Heltec 3D printable case see this [design](https://www.thingiverse.com/thing:3125854) by [ornotermes](https://www.thingiverse.com/ornotermes).
@@ -75,4 +76,4 @@ Most of these problems should be solved by the beta release:
* The mesh protocol is turned off for now, currently we only send packets one hop distant
* No one has written an iOS app yet ;-)
For more details see the [device software TODO](https://github.com/geeksville/Meshtastic-esp32/blob/master/TODO.md) or the [Android app TODO](https://github.com/geeksville/Meshtastic-Android/blob/master/TODO.md).
For more details see the [device software TODO](https://github.com/meshtastic/Meshtastic-esp32/blob/master/TODO.md) or the [Android app TODO](https://github.com/meshtastic/Meshtastic-Android/blob/master/TODO.md).

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,7 +5,7 @@ We don't collect any personal identifying information.
If you have opted-in to analytics (thank you - that helps us know what things we need to improve), we'll receive anonymized information about user behavior. i.e. which screens you used in the app etc... We never
capture usernames, the contents of your texts or your location.
This is an open-source project run by hobbyists and we try to be completely transparent. If you have questions on this policy, please file [a github issue](https://github.com/geeksville/meshtastic-esp32/issues) and we'll reply/clarify/correct.
This is an open-source project run by hobbyists and we try to be completely transparent. If you have questions on this policy, please file [a github issue](https://github.com/meshtastic/meshtastic-esp32/issues) and we'll reply/clarify/correct.
Keep being awesome!

View File

@@ -2,13 +2,11 @@
"name": "BluetoothOTA",
"keywords": "esp32, bluetooth",
"description": "A BTLE based software OTA update tool",
"repository":
{
"repository": {
"type": "git",
"url": "https://github.com/geeksville/fixme.git"
},
"authors":
[
"authors": [
{
"name": "Kevin Hester",
"email": "kevinh@geeksville.com",
@@ -20,7 +18,15 @@
"frameworks": "arduino",
"platforms": "*",
"dependencies": [
{ "name": "Update" },
{ "name": "ESP32 BLE Arduino" }
{
"name": "Update"
},
{
"name": "ESP32 BLE Arduino"
},
{
"name": "arduino-fsm",
"version": "https://github.com/meshtastic/arduino-fsm.git"
}
]
}
}

View File

@@ -31,6 +31,13 @@ public:
if (!canBegin)
// Indicate failure by forcing the size to 0
c->setValue(0UL);
else {
// This totally breaks abstraction to up up into the app layer for this, but quick hack to make sure we only
// talk to one service during the sw update.
//DEBUG_MSG("FIXME, crufty shutdown of mesh bluetooth for sw update.");
//void stopMeshBluetoothService();
//stopMeshBluetoothService();
}
}
};
@@ -101,6 +108,8 @@ public:
}
};
void bluetoothRebootCheck()
{
if (rebootAtMsec && millis() > rebootAtMsec)
@@ -117,11 +126,18 @@ e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e write|read total image size, 32 bi
e272ebac-d463-4b98-bc84-5cc1a39ee517 write data, variable sized, recommended 512 bytes, write one for each block of file
4826129c-c22a-43a3-b066-ce8f0d5bacc6 write crc32, write last - writing this will complete the OTA operation, now you can read result
5e134862-7411-4424-ac4a-210937432c77 read|notify result code, readable but will notify when the OTA operation completes
We also implement the following standard GATT entries because SW update probably needs them:
ESP_GATT_UUID_SW_VERSION_STR/0x2a28
ESP_GATT_UUID_MANU_NAME/0x2a29
ESP_GATT_UUID_HW_VERSION_STR/0x2a27
*/
BLEService *createUpdateService(BLEServer *server)
BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::string swVersion, std::string hwVersion)
{
// Create the BLE Service
BLEService *service = server->createService("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30");
BLEService *service = server->createService(BLEUUID("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"), 25, 0);
assert(!resultC);
resultC = new BLECharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
@@ -133,10 +149,23 @@ BLEService *createUpdateService(BLEServer *server)
resultC->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
BLECharacteristic *swC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
swC->setValue(swVersion);
service->addCharacteristic(addBLECharacteristic(swC));
BLECharacteristic *mfC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_MANU_NAME), BLECharacteristic::PROPERTY_READ);
mfC->setValue(hwVendor);
service->addCharacteristic(addBLECharacteristic(mfC));
BLECharacteristic *hwvC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
hwvC->setValue(hwVersion);
service->addCharacteristic(addBLECharacteristic(hwvC));
return service;
}
void destroyUpdateService() {
void destroyUpdateService()
{
assert(resultC);
resultC = NULL;

View File

@@ -2,7 +2,7 @@
#include <Arduino.h>
BLEService *createUpdateService(BLEServer* server);
BLEService *createUpdateService(BLEServer* server, std::string hwVendor, std::string swVersion, std::string hwVersion);
void destroyUpdateService();
void bluetoothRebootCheck();

View File

@@ -276,7 +276,7 @@ BLEServer *initBLE(std::string deviceName, std::string hwVendor, std::string swV
// We now let users create the battery service only if they really want (not all devices have a battery)
// BLEService *pBattery = createBatteryService(pServer);
pUpdate = createUpdateService(pServer); // We need to advertise this so our android ble scan operation can see it
pUpdate = createUpdateService(pServer, hwVendor, swVersion, hwVersion); // We need to advertise this so our android ble scan operation can see it
// It seems only one service can be advertised - so for now don't advertise our updater
// pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID());

View File

@@ -1 +0,0 @@
../MeshUtil/app/src/main/proto/mesh.options

View File

@@ -1 +0,0 @@
../MeshUtil/app/src/main/proto/mesh.proto

View File

@@ -21,8 +21,8 @@ framework = arduino
board_build.partitions = partition-table.csv
; note: we add src to our include search path so that lmic_project_config can override
; FIXME fix dependencies on arduino-fsm
build_flags = -Wall -Wextra -Wno-missing-field-initializers -I.pio/libdeps/esp32/arduino-fsm -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
build_flags = -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial
; not needed included in ttgo-t-beam board file
; also to use PSRAM https://docs.platformio.org/en/latest/platforms/espressif32.html#external-ram-psram
@@ -55,20 +55,22 @@ debug_tool = jlink
debug_init_break = tbreak setup
; Note: some libraries are specified by #ID where there are conflicting library
; names.
lib_deps =
https://github.com/geeksville/RadioHead.git
TinyGPSPlus
https://github.com/geeksville/esp8266-oled-ssd1306.git ; ESP8266_SSD1306
https://github.com/meshtastic/RadioHead.git
1655 ; TinyGPSPlus
https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306
AXP202X_Library
SPI
OneButton
CRC32 ; explicitly needed because dependency is missing in the ble ota update lib
1260 ; OneButton
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
Wire ; explicitly needed here because the AXP202 library forgets to add it
https://github.com/geeksville/arduino-fsm.git
https://github.com/meshtastic/arduino-fsm.git
;[env:tbeam]
;board = ttgo-t-beam
;[env:heltec]
;build_type = debug ; to make it possible to step through our jtag debugger
;board = heltec_wifi_lora_32_V2
;board = heltec_wifi_lora_32_V2

1
proto Submodule

Submodule proto added at e1a48b6e75

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is kept in source control because it reflects the last stable
release. It is used by the android app for forcing software updates. Do not edit.
Generated by bin/buildall.sh -->
<resources>
<string name="cur_firmware_version">0.0.5</string>
</resources>

View File

@@ -33,8 +33,8 @@ public:
void onRead(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onRead(c);
DEBUG_MSG("Got proto read\n");
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), fields, my_struct);
DEBUG_MSG("pbread from %s returns %d bytes\n", c->getUUID().toString().c_str(), numbytes);
c->setValue(trBytes, numbytes);
}
@@ -51,8 +51,8 @@ protected:
bool writeToDest(BLECharacteristic *c, void *dest)
{
// dumpCharacteristic(pCharacteristic);
DEBUG_MSG("Got on proto write\n");
std::string src = c->getValue();
DEBUG_MSG("pbwrite to %s of %d bytes\n", c->getUUID().toString().c_str(), src.length());
return pb_decode_from_bytes((const uint8_t *)src.c_str(), src.length(), fields, dest);
}
};
@@ -88,7 +88,7 @@ public:
void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);
DEBUG_MSG("Got on nodeinfo write\n");
DEBUG_MSG("Reset nodeinfo read pointer\n");
nodeDB.resetReadPointer();
}
};
@@ -188,19 +188,18 @@ public:
}
else
{
DEBUG_MSG("delivering toPhone packet to phone\n");
static FromRadio fRadio;
static FromRadio fradio;
// Encapsulate as a FromRadio packet
memset(&fRadio, 0, sizeof(fRadio));
fRadio.which_variant = FromRadio_packet_tag;
fRadio.variant.packet = *mp;
// Encapsulate as a ToRadio packet
memset(&fradio, 0, sizeof(fradio));
fradio.which_variant = FromRadio_packet_tag;
fradio.variant.packet = *mp;
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), FromRadio_fields, &fRadio);
DEBUG_MSG("delivering toPhone packet to phone %d bytes\n", numbytes);
c->setValue(trBytes, numbytes);
service.releaseToPool(mp); // we just copied the bytes, so don't need this buffer anymore
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), FromRadio_fields, &fradio);
c->setValue(trBytes, numbytes);
}
}
};
@@ -333,7 +332,8 @@ BLEService *createMeshBluetoothService(BLEServer *server)
void destroyMeshBluetoothService()
{
assert(meshService);
meshService->stop();
delete meshService;
meshFromNumCharacteristic = NULL;
}
}

View File

@@ -11,3 +11,9 @@ void destroyMeshBluetoothService();
* Tell any bluetooth clients that the number of rx packets has changed
*/
void bluetoothNotifyFromNum(uint32_t newValue);
/**
* Super skanky FIXME - when we start a software update we force the mesh service to shutdown.
* If the sw update fails, the user will have to manually reset the board to get things running again.
*/
void stopMeshBluetoothService();

View File

@@ -123,10 +123,33 @@ MeshPacket *MeshService::handleFromRadioUser(MeshPacket *mp)
return mp;
}
void MeshService::handleIncomingPosition(MeshPacket *mp)
{
if (mp->has_payload && mp->payload.which_variant == SubPacket_position_tag)
{
DEBUG_MSG("handled incoming position time=%u\n", mp->payload.variant.position.time);
if (mp->payload.variant.position.time)
{
struct timeval tv;
uint32_t secs = mp->payload.variant.position.time;
tv.tv_sec = secs;
tv.tv_usec = 0;
gps.perhapsSetRTC(&tv);
}
}
}
void MeshService::handleFromRadio(MeshPacket *mp)
{
mp->rx_time = gps.getValidTime(); // store the arrival timestamp for the phone
// If it is a position packet, perhaps set our clock (if we don't have a GPS of our own, otherwise wait for that to work)
if(!myNodeInfo.has_gps)
handleIncomingPosition(mp);
if (mp->has_payload && mp->payload.which_variant == SubPacket_user_tag)
{
mp = handleFromRadioUser(mp);
@@ -149,7 +172,7 @@ void MeshService::handleFromRadio(MeshPacket *mp)
}
assert(toPhoneQueue.enqueue(mp, 0) == pdTRUE); // FIXME, instead of failing for full queue, delete the oldest mssages
if(mp->payload.want_response)
if (mp->payload.want_response)
sendNetworkPing(mp->from);
}
else
@@ -168,12 +191,11 @@ void MeshService::handleFromRadio()
bluetoothNotifyFromNum(fromNum);
}
uint32_t sendOwnerCb()
{
service.sendOurOwner();
service.sendOurOwner();
return radioConfig.preferences.send_owner_interval * radioConfig.preferences.position_broadcast_secs * 1000;
return radioConfig.preferences.send_owner_interval * radioConfig.preferences.position_broadcast_secs * 1000;
}
Periodic sendOwnerPeriod(sendOwnerCb);
@@ -209,17 +231,7 @@ void MeshService::handleToRadio(std::string s)
case ToRadio_packet_tag:
{
// If our phone is sending a position, see if we can use it to set our RTC
if (r.variant.packet.has_payload && r.variant.packet.payload.which_variant == SubPacket_position_tag && r.variant.packet.payload.variant.position.time)
{
struct timeval tv;
uint32_t secs = r.variant.packet.payload.variant.position.time;
// FIXME, this is a shit not right version of the standard def of unix time!!!
tv.tv_sec = secs;
tv.tv_usec = 0;
gps.perhapsSetRTC(&tv);
}
handleIncomingPosition(&r.variant.packet); // If it is a position packet, perhaps set our clock
r.variant.packet.rx_time = gps.getValidTime(); // Record the time the packet arrived from the phone (so we update our nodedb for the local node)
@@ -247,8 +259,14 @@ void MeshService::sendToMesh(MeshPacket *p)
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other nodes shouldn't trust it anyways)
// Note: for now, we allow a device with a local GPS to include the time, so that gpsless devices can get time.
if (p->has_payload && p->payload.which_variant == SubPacket_position_tag)
p->payload.variant.position.time = 0;
{
if (!myNodeInfo.has_gps)
p->payload.variant.position.time = 0;
else
DEBUG_MSG("Providing time to mesh %u\n", p->payload.variant.position.time);
}
// If the phone sent a packet just to us, don't send it out into the network
if (p->to == nodeDB.getNodeNum())
@@ -295,8 +313,7 @@ void MeshService::sendOurPosition(NodeNum dest)
p->to = dest;
p->payload.which_variant = SubPacket_position_tag;
p->payload.variant.position = node->position;
// FIXME - for now we are leaving this in the sent packets (for debugging)
//p->payload.variant.position.time = 0; // No need to send time, other node won't trust it anyways
p->payload.variant.position.time = gps.getValidTime(); // This nodedb timestamp might be stale, so update it if our clock is valid.
sendToMesh(p);
}

View File

@@ -86,6 +86,9 @@ private:
/// handle a user packet that just arrived on the radio, return NULL if we should not process this packet at all
MeshPacket *handleFromRadioUser(MeshPacket *mp);
/// look at inbound packets and if they contain a position with time, possibly set our clock
void handleIncomingPosition(MeshPacket *mp);
};
extern MeshService service;

View File

@@ -64,6 +64,9 @@ void NodeDB::init()
// some hardware defaults to have a built in GPS
myNodeInfo.has_gps = true;
#endif
strncpy(myNodeInfo.region, xstr(HW_VERSION), sizeof(myNodeInfo.region));
strncpy(myNodeInfo.firmware_version, xstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
strncpy(myNodeInfo.hw_model, HW_VENDOR, sizeof(myNodeInfo.hw_model));
// Init our blank owner info to reasonable defaults
esp_efuse_mac_get_default(ourMacAddr);
@@ -275,7 +278,7 @@ void NodeDB::updateFrom(const MeshPacket &mp)
devicestate.rx_text_message = mp;
devicestate.has_rx_text_message = true;
updateTextMessage = true;
powerFSM.trigger(EVENT_NODEDB_UPDATED);
powerFSM.trigger(EVENT_RECEIVED_TEXT_MSG);
}
}
break;

View File

@@ -6,6 +6,7 @@
#include "screen.h"
#include "PowerFSM.h"
#include "GPS.h"
#include "main.h"
static void sdsEnter()
{
@@ -28,6 +29,8 @@ static void lsEnter()
delay(10); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
gps.prepareSleep(); // abandon in-process parsing
if(!isUSBPowered) // FIXME - temp hack until we can put gps in sleep mode, if we have AC when we go to sleep then leave GPS on
setGPSPower(false); // kill GPS power
}
@@ -120,8 +123,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
powerFSM.add_transition(&stateNB, &stateON, EVENT_PRESS, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateNB, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
@@ -130,6 +133,7 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); // restarts the sleep timer
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Fsm.h"
#include <Fsm.h>
// See sw-design.md for documentation
@@ -16,4 +16,4 @@
extern Fsm powerFSM;
void PowerFSM_setup();
void PowerFSM_setup();

View File

@@ -29,21 +29,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Version
// -----------------------------------------------------------------------------
#define APP_NAME "Meshtastic"
// If app version is not specified we assume we are not being invoked by the build script
#ifndef APP_VERSION
#define APP_VERSION "0.0.0" // this def normally comes from build-all.sh
#define APP_VERSION 0.0.0 // this def normally comes from build-all.sh
#define HW_VERSION 1.0 - US // normally comes from build-all.sh and contains the region code
#endif
// -----------------------------------------------------------------------------
// Configuration
// -----------------------------------------------------------------------------
// Select which board is being used. If the outside build environment has sent a choice, just use that
#if !defined(T_BEAM_V10) && !defined(HELTEC_LORA32)
//#define T_BEAM_V10 // AKA Rev1 (second board released)
// #define T_BEAM_V10 // AKA Rev1 (second board released)
#define HELTEC_LORA32
#define HW_VERSION_US // We encode the hardware freq range in the hw version string, so sw update can eventually install the correct build
@@ -55,18 +53,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define USE_JTAG
#endif
#define DEBUG_PORT Serial // Serial debug port
#define SERIAL_BAUD 115200 // Serial debug baud rate
#define DEBUG_PORT Serial // Serial debug port
#define SERIAL_BAUD 115200 // Serial debug baud rate
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
#define xstr(s) str(s)
#define str(s) #s
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
#ifdef DEBUG_PORT
#define DEBUG_MSG(...) DEBUG_PORT.printf( __VA_ARGS__ )
#define DEBUG_MSG(...) DEBUG_PORT.printf(__VA_ARGS__)
#else
#define DEBUG_MSG(...)
#endif
@@ -81,15 +81,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// GPS
// -----------------------------------------------------------------------------
#define GPS_SERIAL_NUM 1
#define GPS_BAUDRATE 9600
#define GPS_SERIAL_NUM 1
#define GPS_BAUDRATE 9600
#if defined(T_BEAM_V10)
#define GPS_RX_PIN 34
#define GPS_RX_PIN 34
#ifdef USE_JTAG
#define GPS_TX_PIN -1
#define GPS_TX_PIN -1
#else
#define GPS_TX_PIN 12
#define GPS_TX_PIN 12
#endif
#endif
@@ -97,59 +97,59 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// LoRa SPI
// -----------------------------------------------------------------------------
#define SCK_GPIO 5
#define MISO_GPIO 19
#define MOSI_GPIO 27
#define NSS_GPIO 18
#define SCK_GPIO 5
#define MISO_GPIO 19
#define MOSI_GPIO 27
#define NSS_GPIO 18
#if defined(T_BEAM_V10)
#define HW_VENDOR "TTGO"
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR "TBEAM"
#define BICOLOR_DISPLAY // we have yellow at the top 16 lines
#define I2C_SDA 21
#define I2C_SCL 22
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON_PIN 38
#define BUTTON_PIN 38
#ifndef USE_JTAG
#define RESET_GPIO 14
#define RESET_GPIO 14
#endif
#define DIO0_GPIO 26
#define DIO1_GPIO 33 // Note: not really used on this board
#define DIO2_GPIO 32 // Note: not really used on this board
#define DIO0_GPIO 26
#define DIO1_GPIO 33 // Note: not really used on this board
#define DIO2_GPIO 32 // Note: not really used on this board
// Leave undefined to disable our PMU IRQ handler
#define PMU_IRQ 35
// Leave undefined to disable our PMU IRQ handler
#define PMU_IRQ 35
#elif defined(HELTEC_LORA32)
#define HW_VENDOR "Heltec"
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR "HELTEC"
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
#define I2C_SDA 4
#define I2C_SCL 15
#define I2C_SDA 4
#define I2C_SCL 15
#endif
#define RESET_OLED 16
#define RESET_OLED 16
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25
#define BUTTON_PIN 0
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25
#define BUTTON_PIN 0
#ifndef USE_JTAG
#define RESET_GPIO 14
#define RESET_GPIO 14
#endif
#define DIO0_GPIO 26
#define DIO1_GPIO 35
#define DIO2_GPIO 34
#define DIO0_GPIO 26
#define DIO1_GPIO 35
#define DIO2_GPIO 34
#endif
// -----------------------------------------------------------------------------
// AXP192 (Rev1-specific options)
// -----------------------------------------------------------------------------
// #define AXP192_SLAVE_ADDRESS 0x34 // Now defined in axp20x.h
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2

View File

@@ -52,10 +52,7 @@ bool isUSBPowered;
bool ssd1306_found;
bool axp192_found;
bool bluetoothOn;
#define xstr(s) str(s)
#define str(s) #s
bool bluetoothOn;
// -----------------------------------------------------------------------------
// Application
@@ -175,8 +172,8 @@ void axp192Init()
axp.clearIRQ();
#endif
isCharging = axp.isChargeing();
isUSBPowered = axp.isVBUSPlug();
isCharging = axp.isChargeing() ? 1 : 0;
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
}
else
{
@@ -201,8 +198,6 @@ const char *getDeviceName()
return name;
}
void setup()
{
// Debug
@@ -240,7 +235,7 @@ void setup()
#endif
// Hello
DEBUG_MSG("%s %s\n", xstr(APP_NAME), str(APP_VERSION));
DEBUG_MSG("Meshtastic swver=%s, hwver=%s\n", xstr(APP_VERSION), xstr(HW_VERSION));
// Don't init display if we don't have one or we are waking headless due to a timer event
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
@@ -270,7 +265,7 @@ void initBluetooth()
// FIXME - we are leaking like crazy
// AllocatorScope scope(btPool);
BLEServer *serve = initBLE(getDeviceName(), HW_VENDOR, str(APP_VERSION)); // FIXME, use a real name based on the macaddr
BLEServer *serve = initBLE(getDeviceName(), HW_VENDOR, xstr(APP_VERSION), xstr(HW_VERSION)); // FIXME, use a real name based on the macaddr
createMeshBluetoothService(serve);
// Start advertising - this must be done _after_ creating all services
@@ -288,7 +283,7 @@ void setBluetoothEnable(bool on)
{
Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap());
//ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
initBluetooth();
initBluetooth();
}
else
{
@@ -356,11 +351,15 @@ void loop()
DEBUG_MSG("pmu irq!\n");
isCharging = axp.isChargeing();
isUSBPowered = axp.isVBUSPlug();
isCharging = axp.isChargeing() ? 1 : 0;
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
axp.clearIRQ();
}
// FIXME AXP192 interrupt is not firing, remove this temporary polling of battery state
isCharging = axp.isChargeing() ? 1 : 0;
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
#endif
}
#endif

View File

@@ -1,4 +1,6 @@
#pragma once
extern bool axp192_found;
extern bool ssd1306_found;
extern bool ssd1306_found;
extern bool isCharging;
extern bool isUSBPowered;

View File

@@ -33,8 +33,8 @@ typedef enum _ChannelSettings_ModemConfig {
typedef enum _DeviceState_Version {
DeviceState_Version_Unset = 0,
DeviceState_Version_Minimum = 16,
DeviceState_Version_Current = 16
DeviceState_Version_Minimum = 17,
DeviceState_Version_Current = 17
} DeviceState_Version;
/* Struct definitions */
@@ -56,6 +56,9 @@ typedef struct _MyNodeInfo {
int32_t my_node_num;
bool has_gps;
int32_t num_channels;
char region[12];
char hw_model[12];
char firmware_version[12];
} MyNodeInfo;
typedef struct _Position {
@@ -63,7 +66,6 @@ typedef struct _Position {
double longitude;
int32_t altitude;
int32_t battery_level;
bool from_hardware;
uint32_t time;
} Position;
@@ -176,7 +178,7 @@ typedef struct _ToRadio {
/* Initializer values for message structs */
#define Position_init_default {0, 0, 0, 0, 0, 0}
#define Position_init_default {0, 0, 0, 0, 0}
#define Data_init_default {_Data_Type_MIN, {0, {0}}}
#define User_init_default {"", "", "", {0}}
#define SubPacket_init_default {0, {Position_init_default}, 0}
@@ -185,11 +187,11 @@ typedef struct _ToRadio {
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0, "", "", ""}
#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default}, _DeviceState_Version_MIN, false, MeshPacket_init_default}
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
#define Position_init_zero {0, 0, 0, 0, 0, 0}
#define Position_init_zero {0, 0, 0, 0, 0}
#define Data_init_zero {_Data_Type_MIN, {0, {0}}}
#define User_init_zero {"", "", "", {0}}
#define SubPacket_init_zero {0, {Position_init_zero}, 0}
@@ -198,7 +200,7 @@ typedef struct _ToRadio {
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0, "", "", ""}
#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero}, _DeviceState_Version_MIN, false, MeshPacket_init_zero}
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@@ -214,11 +216,13 @@ typedef struct _ToRadio {
#define MyNodeInfo_my_node_num_tag 1
#define MyNodeInfo_has_gps_tag 2
#define MyNodeInfo_num_channels_tag 3
#define MyNodeInfo_region_tag 4
#define MyNodeInfo_hw_model_tag 5
#define MyNodeInfo_firmware_version_tag 6
#define Position_latitude_tag 1
#define Position_longitude_tag 2
#define Position_altitude_tag 3
#define Position_battery_level_tag 4
#define Position_from_hardware_tag 5
#define Position_time_tag 6
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
#define RadioConfig_UserPreferences_send_owner_interval_tag 2
@@ -269,7 +273,6 @@ X(a, STATIC, SINGULAR, DOUBLE, latitude, 1) \
X(a, STATIC, SINGULAR, DOUBLE, longitude, 2) \
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
X(a, STATIC, SINGULAR, INT32, battery_level, 4) \
X(a, STATIC, SINGULAR, BOOL, from_hardware, 5) \
X(a, STATIC, SINGULAR, UINT32, time, 6)
#define Position_CALLBACK NULL
#define Position_DEFAULT NULL
@@ -356,7 +359,10 @@ X(a, STATIC, SINGULAR, INT32, frequency_error, 6)
#define MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, INT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
X(a, STATIC, SINGULAR, INT32, num_channels, 3)
X(a, STATIC, SINGULAR, INT32, num_channels, 3) \
X(a, STATIC, SINGULAR, STRING, region, 4) \
X(a, STATIC, SINGULAR, STRING, hw_model, 5) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 6)
#define MyNodeInfo_CALLBACK NULL
#define MyNodeInfo_DEFAULT NULL
@@ -420,7 +426,7 @@ extern const pb_msgdesc_t ToRadio_msg;
#define ToRadio_fields &ToRadio_msg
/* Maximum encoded size of messages (where known) */
#define Position_size 48
#define Position_size 46
#define Data_size 256
#define User_size 72
#define SubPacket_size 261
@@ -428,9 +434,9 @@ extern const pb_msgdesc_t ToRadio_msg;
#define ChannelSettings_size 50
#define RadioConfig_size 126
#define RadioConfig_UserPreferences_size 72
#define NodeInfo_size 157
#define MyNodeInfo_size 24
#define DeviceState_size 15085
#define NodeInfo_size 155
#define MyNodeInfo_size 63
#define DeviceState_size 15060
#define FromRadio_size 301
#define ToRadio_size 295

View File

@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "screen.h"
#include "mesh-pb-constants.h"
#include "NodeDB.h"
#include "main.h"
#define FONT_HEIGHT 14 // actually 13 for "ariel 10" but want a little extra space
#define FONT_HEIGHT_16 (ArialMT_Plain_16[1] + 1)
@@ -442,8 +443,12 @@ void drawDebugInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, i
static char channelStr[20];
snprintf(channelStr, sizeof(channelStr), "%s", channelSettings.name);
// We don't show battery levels yet - for now just lie and show debug info
static char batStr[20];
snprintf(batStr, sizeof(channelStr), "Batt %x%%", (isCharging << 1) + isUSBPowered);
const char *fields[] = {
"Batt 89%",
batStr,
"GPS 75%",
usersStr,
channelStr,
@@ -505,7 +510,7 @@ void Screen::setOn(bool on)
}
}
static void screen_print(const char *text, uint8_t x, uint8_t y, uint8_t alignment)
void screen_print(const char *text, uint8_t x, uint8_t y, uint8_t alignment)
{
DEBUG_MSG(text);
@@ -704,4 +709,4 @@ void Screen::onPress()
targetFramerate = TRANSITION_FRAMERATE;
ui.setTargetFPS(targetFramerate);
}
}
}

View File

@@ -3,6 +3,7 @@
#include "PeriodicTask.h"
void screen_print(const char * text);
void screen_print(const char * text, uint8_t x, uint8_t y, uint8_t alignment);
// Show the bluetooth PIN screen
@@ -36,4 +37,4 @@ public:
void onPress();
};
extern Screen screen;
extern Screen screen;