Muon GNSS - is this working yet?

I've just set up my new Muon but haven't been able to get any results using the particle-som-gnss "Usage" example and just wondering if it should be working at this point.
I have all antennas connected, including the Parantg1 GNSS antenna. The Usage example (modified to include "fix" as a variable) seems to be installing correctly but but the "fix" always seems to be false.

The particle-som-gnss library should work with the M404 (United States, Canada, Mexico) Muon. It does not yet work with the M524 (EMEAA) version.

You probably will not be able to get a GNSS fix indoors, which is also the case for other devices like the Tracker One and Monitor One.

Still no luck, even with the Muon/M404 placed outdoors. Perhaps it's a power issue? It was running only on the battery both times. Would it need USB C as well as the battery? The M404 seemed to be running fine, reporting when asked, but perhaps the antenna needs both battery and USB C?

As a side note, the battery went dead overnight (the Muon/M404 was running only off the battery), and the battery did not seem to charge when I plugged in the USB C connector (no Charge LED). As well, the Muon did not start.

I removed the M404 and applied 12V to the Muon through the DC IN terminals. After 4 hours I disconnected the 12v power and battery, reinstalled the M404, connected the battery and the USB C. Still no Charge LED on the Muon but the M404 started. When I disconnected the USB C power and placed the Muon/M404 outdoors, the vitals showed only a 3% battery charge. Would that be expected after 3 or 4 hours charging with 12V on DC IN? Will the USB C charge the battery at all?

Also, is it ok to have the M404 installed on the Muon with 12V applied to DC IN? I tried it briefly but the power supply current jumped from 40 ma to over 200ma (I didn't leave it connected, so don't know where the input current would have leveld off.)

I tested the Muon 404 and was able to get a lock using the particle-som-gnss library on battery only.

The battery should charge in 4 hours off 12 VDC input.

The battery should also charge off USB-C, but only from a real USB-C port. If you are using a USB-A to USB-C cable, the USB port won't switch to 9V and the battery will not charge, and the Muon won't run (except off battery).

3 Likes

That's a subtle and important detail - thank you.

2 Likes

Thanks for responding Rick. I still can't seem to make this work. The Muon/M404 is outside and on battery power. I'm using the Usage example, modified to publish the location on request. Should I be doing/enabling something else as well?
Thanks.

/*
 * Copyright (c) 2024 Particle Industries, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Particle.h"
#include "location.h"

SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);
bool fix = false;

SerialLogHandler logHandler(LOG_LEVEL_INFO);

void setup() {
    waitFor(Serial.isConnected, 10000);

    LocationConfiguration config;
    config.enableAntennaPower(GNSS_ANT_PWR);
    Location.begin(config);
    Particle.function("Publish Now",publishNow);
    Particle.variable("Fix",fix);
}

LocationPoint point = {};
bool ready = true;

void getCb(LocationResults results) {
    Log.info("async callback returned %d", (int)results);
    if (results == LocationResults::Fixed)
        Log.info("async callback reporting fixed");
}

int publishNow(String pub) {
    Particle.publish("location", String::format("%f, %f, %.0f", point.latitude, point.longitude, point.altitude), PRIVATE);
    return (1);
    }
    
void loop() {
    if (Serial.available()) {
        char c = (char)Serial.read();
        fix = false;
        switch (c) {
            case 'g': {
                Location.getLocation(point, getCb, true);
                Log.info("GNSS acquistion started");
                break;
            }

            case 'p': {
                auto fixed = (point.fix) ? true : false;
                if (fixed) {
                    fix = true;
                    Log.info("Position fixed!");
                    Log.info("Lat %0.5lf, lon %0.5lf", point.latitude, point.longitude);
                    Log.info("Alt %0.1f m, speed %0.1f m/s, heading %0.1f deg", point.altitude, point.speed, point.heading);
                }
                else {
                    Log.info("Position not fixed. :(");
                    fix = false;
                }
                break;
            }
        }
    }
}

It looks like you're not ever calling getLocation(). That's required to start scanning for satellites.

This is the firmware I used to test:

/*
 * Copyright (c) 2024 Particle Industries, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Particle.h"
#include "location.h"

SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);

SerialLogHandler logHandler(LOG_LEVEL_INFO);
enum class State {
    START,
    ACQUIRING,
    CALLBACK_RECEIVED,
    RETRY,
    IDLE
};
State state = State::START;

void setup() {
    // waitFor(Serial.isConnected, 10000);

    LocationConfiguration config;
    config.enableAntennaPower(GNSS_ANT_PWR);
    Location.begin(config);
}

LocationResults locationResults;
LocationPoint locationPoint = {};
unsigned long stateTime = 0;
const std::chrono::milliseconds retryPeriod = 30s;

void getLocationCallback(LocationResults results) {
    locationResults = results;
    Log.info("async callback returned %d", (int)locationResults);
    state = State::CALLBACK_RECEIVED;
}

void loop() {
    if (state == State::START) {
        if (Particle.connected()) {
            Location.getLocation(locationPoint, getLocationCallback, true);
            Log.info("GNSS acquisition started");
            state = State::ACQUIRING;
        }
    }
    else
    if (state == State::CALLBACK_RECEIVED) {

        Log.info("Position fixed!");
        Log.info("Lat %0.5lf, lon %0.5lf", locationPoint.latitude, locationPoint.longitude);
        Log.info("Alt %0.1f m, speed %0.1f m/s, heading %0.1f deg", locationPoint.altitude, locationPoint.speed, locationPoint.heading);

        if (locationPoint.fix) {
            state = State::IDLE;
        }
        else {
            state = State::RETRY;
            stateTime = millis();
        }
    }
    else
    if (state == State::RETRY) {
        if (millis() - stateTime >= retryPeriod.count()) {
            state = State::START;
            Log.info("retrying acquisition");
        }
    }

}

Once the device connects to cellular it will start trying to acquire the location. In my test, it took 34 seconds, but it could take longer. Then it will publish the loc event. I monitored the event log in the console for that.

If it does not get a lock and times out, it will try again in 30 seconds.

1 Like

Great! That works for me as well. There must be something in the particle-som-gnss library Usage example that I haven't figured out yet. Your code works well.
Thanks again!

I was able to get the Usage example to work, but the example from Rick looks like the better way to go. With the Usage example you need to be connected to a terminal and send the g and then p characters to return the fixed position.

Hey, I can't find the Particle.publish() in this code.
I'm interested in it so the device can generate a loc event and populate the little map on the Particle console.
Thanks!

Apologies, the publish is inside the particle-som-gnss library. :roll_eyes:

Thanks, it would have taken me a while to figure that out :slight_smile:

Yes, I invested in a real USB C power adapter and the battery now charges off of the USB C connection

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.