Skip to content

Commit

Permalink
Merge pull request #58 from geeksville/master
Browse files Browse the repository at this point in the history
kevins bug fixes for weds
  • Loading branch information
geeksville authored Mar 25, 2020
2 parents 9075501 + 4d54df4 commit 4c35d1f
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 50 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions bin/start-terminal1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pio device monitor -p /dev/ttyUSB1 -b 115200
2 changes: 1 addition & 1 deletion bin/version.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export VERSION=0.1.9
export VERSION=0.1.10
62 changes: 32 additions & 30 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,55 @@
# What is Meshtastic?

Meshtastic is a project that lets you use
inexpensive ($30 ish) GPS 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
members and any text messages sent to your group chat.
inexpensive (\$30 ish) GPS 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 members and any text messages sent to your group chat.

The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios
will optionally work with your phone, but no phone is required.
The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios will optionally work with your phone, but no phone is required.

Note: Questions after reading this? See our new [forum](https://meshtastic.discourse.group/).

### Uses

* Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..)
* Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...)
* Secure long-range communication within groups without depending on cellular providers
* Finding your lost kids ;-)
- Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..)
- Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...)
- Secure long-range communication within groups without depending on cellular providers
- Finding your lost kids ;-)

[![Youtube video demo](desk-video-screenshot.png)](https://www.youtube.com/watch?v=WlNbMbVZlHI "Meshtastic early demo")

### Features
Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?)

* Very long battery life (should be about eight days with the beta software)
* Built in GPS and [LoRa](https://en.wikipedia.org/wiki/LoRa) radio, but we manage the radio automatically for you
* Long range - a few miles per node but each node will forward packets as needed
* Shows direction and distance to all members of your channel
* Directed or broadcast text messages for channel members
* 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 friends and they can join your encrypted mesh


Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?)

- Very long battery life (should be about eight days with the beta software)
- Built in GPS and [LoRa](https://en.wikipedia.org/wiki/LoRa) radio, but we manage the radio automatically for you
- Long range - a few miles per node but each node will forward packets as needed
- Shows direction and distance to all members of your channel
- Directed or broadcast text messages for channel members
- 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 friends and they can join your encrypted mesh

This project is currently in early alpha - if you have questions please [join our discussion forum](https://meshtastic.discourse.group/).

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 [forum](https://meshtastic.discourse.group/).
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 [forum](https://meshtastic.discourse.group/).

# Updates

Note: Updates are happening almost daily, only major updates are listed below. For more details see our chat, github releases or the Android alpha tester emails.
Note: Updates are happening almost daily, only major updates are listed below. For more details see our chat, github releases or the Android alpha tester emails.

* 03/03/2020 - 0.0.9 of the Android app and device code is released. Still an alpha but fairly functional.
* 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.
- 03/03/2020 - 0.0.9 of the Android app and device code is released. Still an alpha but fairly functional.
- 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

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)

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:
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.
Expand All @@ -57,8 +58,9 @@ But if you want the bleeding edge app now, we'd love to have your help testing.
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 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.

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/meshtastic/Meshtastic-esp32/blob/master/README.md).

Expand Down
7 changes: 6 additions & 1 deletion src/MeshRadio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,16 @@ ErrorCode MeshRadio::send(MeshPacket *p)

void MeshRadio::loop()
{
// It should never take us more than 30 secs to send a packet, if it does, we have a bug
// It should never take us more than 30 secs to send a packet, if it does, we have a bug, FIXME, move most of this
// into CustomRF95
uint32_t now = millis();
if (lastTxStart != 0 && (now - lastTxStart) > TX_WATCHDOG_TIMEOUT && rf95.mode() == RHGenericDriver::RHModeTx) {
DEBUG_MSG("ERROR! Bug! Tx packet took too long to send, forcing radio into rx mode");
rf95.setModeRx();
if (rf95.sendingPacket) { // There was probably a packet we were trying to send, free it
rf95.pool.release(rf95.sendingPacket);
rf95.sendingPacket = NULL;
}
recordCriticalError(ErrTxWatchdog);
lastTxStart = 0; // Stop checking for now, because we just warned the developer
}
Expand Down
23 changes: 16 additions & 7 deletions src/MeshService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ void MeshService::init()
// sendOwnerPeriod();
}

void MeshService::sendOurOwner(NodeNum dest)
void MeshService::sendOurOwner(NodeNum dest, bool wantReplies)
{
MeshPacket *p = allocForSending();
p->to = dest;
p->payload.want_response = wantReplies;
p->payload.which_variant = SubPacket_user_tag;
User &u = p->payload.variant.user;
u = owner;
Expand Down Expand Up @@ -138,6 +139,8 @@ void MeshService::handleIncomingPosition(MeshPacket *mp)

gps.perhapsSetRTC(&tv);
}
} else {
DEBUG_MSG("Ignoring incoming packet - not a position\n");
}
}

Expand All @@ -150,6 +153,9 @@ void MeshService::handleFromRadio(MeshPacket *mp)
// 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);
else {
DEBUG_MSG("Ignoring incoming time, because we have a GPS\n");
}

if (mp->has_payload && mp->payload.which_variant == SubPacket_user_tag) {
mp = handleFromRadioUser(mp);
Expand Down Expand Up @@ -257,9 +263,10 @@ void MeshService::sendToMesh(MeshPacket *p)
// 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) {
if (!myNodeInfo.has_gps)
if (!myNodeInfo.has_gps) {
DEBUG_MSG("Stripping time %u from position send\n", p->payload.variant.position.time);
p->payload.variant.position.time = 0;
else
} else
DEBUG_MSG("Providing time to mesh %u\n", p->payload.variant.position.time);
}

Expand All @@ -285,18 +292,19 @@ MeshPacket *MeshService::allocForSending()
return p;
}

void MeshService::sendNetworkPing(NodeNum dest)
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
{
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node);

DEBUG_MSG("Sending network ping to 0x%x, with position=%d, wantReplies=%d\n", dest, node->has_position, wantReplies);
if (node->has_position)
sendOurPosition(dest);
sendOurPosition(dest, wantReplies);
else
sendOurOwner(dest);
sendOurOwner(dest, wantReplies);
}

void MeshService::sendOurPosition(NodeNum dest)
void MeshService::sendOurPosition(NodeNum dest, bool wantReplies)
{
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node);
Expand All @@ -307,6 +315,7 @@ void MeshService::sendOurPosition(NodeNum dest)
p->to = dest;
p->payload.which_variant = SubPacket_position_tag;
p->payload.variant.position = node->position;
p->payload.want_response = wantReplies;
p->payload.variant.position.time =
gps.getValidTime(); // This nodedb timestamp might be stale, so update it if our clock is valid.
sendToMesh(p);
Expand Down
6 changes: 3 additions & 3 deletions src/MeshService.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ class MeshService : private Observer

/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
/// sends our owner
void sendNetworkPing(NodeNum dest = NODENUM_BROADCAST);
void sendNetworkPing(NodeNum dest, bool wantReplies = false);

/// Send our owner info to a particular node
void sendOurOwner(NodeNum dest = NODENUM_BROADCAST);
void sendOurOwner(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);

private:
/// Broadcasts our last known position
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST);
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);

/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
Expand Down
10 changes: 5 additions & 5 deletions src/NodeDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ DeviceState versions used to be defined in the .proto file but really only this
#define here.
*/

#define DEVICESTATE_CUR_VER 6
#define DEVICESTATE_CUR_VER 7
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER

#define FS SPIFFS
Expand Down Expand Up @@ -67,10 +67,9 @@ void NodeDB::init()
radioConfig.preferences.ls_secs = 60 * 60;
radioConfig.preferences.phone_timeout_secs = 15 * 60;

#ifdef GPS_RX_PIN
// some hardware defaults to have a built in GPS
myNodeInfo.has_gps = true;
#endif
// default to no GPS, until one has been found by probing
myNodeInfo.has_gps = false;

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));
Expand Down Expand Up @@ -333,6 +332,7 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
/// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code, uint32_t address)
{
DEBUG_MSG("NOTE! Recording critical error %d, address=%x\n", code, address);
myNodeInfo.error_code = code;
myNodeInfo.error_address = address;
myNodeInfo.error_count++;
Expand Down
13 changes: 11 additions & 2 deletions src/PowerFSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,23 @@ static void sdsEnter()
doDeepSleep(radioConfig.preferences.sds_secs * 1000LL);
}

#include "error.h"

static void lsEnter()
{
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", radioConfig.preferences.ls_secs);
screen.setOn(false);

while (!service.radio.rf95.canSleep())
uint32_t now = millis();
while (!service.radio.rf95.canSleep()) {
delay(10); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)

if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep
recordCriticalError(ErrSleepEnterWait);
break;
}
}

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
Expand Down Expand Up @@ -112,7 +121,7 @@ static void onEnter()
uint32_t now = millis();

if (now - lastPingMs > 60 * 1000) { // if more than a minute since our last press, ask other nodes to update their state
service.sendNetworkPing();
service.sendNetworkPing(NODENUM_BROADCAST, true);
lastPingMs = now;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/error.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

/// Error codes for critical error
enum CriticalErrorCode { NoError, ErrTxWatchdog };
enum CriticalErrorCode { NoError, ErrTxWatchdog, ErrSleepEnterWait };

/// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code, uint32_t address = 0);
3 changes: 3 additions & 0 deletions src/screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
float bearingToOther = bearing(p.latitude, p.longitude, op.latitude, op.longitude);
float myHeading = estimatedHeading(p.latitude, p.longitude);
headingRadian = bearingToOther - myHeading;
} else {
// Debug info for gps lock errors
// DEBUG_MSG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node));
}

const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
Expand Down

0 comments on commit 4c35d1f

Please sign in to comment.