{"id":26642684,"url":"https://github.com/chrismyers2000/meshadv-mini","last_synced_at":"2025-03-24T19:21:20.822Z","repository":{"id":284067160,"uuid":"916939235","full_name":"chrismyers2000/MeshAdv-Mini","owner":"chrismyers2000","description":"A Raspberry Pi LoRa hat for Meshtastic with GPS, Real-Time Clock, I2C and Qwiic, Temp Sensor and PWM fan control","archived":false,"fork":false,"pushed_at":"2025-03-24T00:32:58.000Z","size":10912,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T01:27:47.314Z","etag":null,"topics":["gps","hat","lora","mesh-networks","meshtastic","meshtasticd","raspberry-pi","raspberrypi"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrismyers2000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-15T03:27:15.000Z","updated_at":"2025-03-24T00:33:01.000Z","dependencies_parsed_at":"2025-03-24T01:37:51.589Z","dependency_job_id":null,"html_url":"https://github.com/chrismyers2000/MeshAdv-Mini","commit_stats":null,"previous_names":["chrismyers2000/meshadv-mini"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrismyers2000%2FMeshAdv-Mini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrismyers2000%2FMeshAdv-Mini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrismyers2000%2FMeshAdv-Mini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrismyers2000%2FMeshAdv-Mini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrismyers2000","download_url":"https://codeload.github.com/chrismyers2000/MeshAdv-Mini/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245334923,"owners_count":20598390,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gps","hat","lora","mesh-networks","meshtastic","meshtasticd","raspberry-pi","raspberrypi"],"created_at":"2025-03-24T19:21:19.739Z","updated_at":"2025-03-24T19:21:20.812Z","avatar_url":"https://github.com/chrismyers2000.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://github.com/chrismyers2000/MeshAdv-Mini/blob/298581bdf106296083a373f97896de44633c6cd1/Data/Misc/MeshAdv%20Mini%20Logo.png)\n\n---\n\n\n==The MeshAdv Mini has not been released, the project and this README is currently in progress==\n\nThe MeshAdv Mini is a Lora/GPS Raspberry Pi hat designed to be used with the Linux-native version of [Meshtastic](https://meshtastic.org/) known as [meshtasticd](https://meshtastic.org/docs/hardware/devices/linux-native-hardware/). It is similar to its big brother, the [MeshAdv Pi Hat](https://github.com/chrismyers2000/MeshAdv-Pi-Hat), but half the size and fits perfectly on the Pi Zero lineup. The board includes a +22dbm LoRa module, integrated GPS module, HAT+ EEPROM, Temperature Sensor, 5V PWM Fan header, and breakout for I2C bus including two Qwiic connectors. \nThis makes for a good \"base station\" or \"Router\" node that can be mounted high on a pole and powered over POE (using separate POE adapter or Hat). No more need to retrieve the node everytime you want to update firmware, it can all be done remotely. It also makes it easy and reliable to connect to MQTT.\n\n---\n\nFully Assembled units available here: https://frequencylabs.etsy.com\n\n\n![](https://github.com/chrismyers2000/MeshAdv-Mini/blob/6fad3e7618cef262edfb8fcbe4b52011aaec8268/Photos/Top_3D_PCB%20MeshAdv%20Mini%20Stackable.png)\n\n== NOTICE!! always have an antenna connected to the LoRa module when powered on, failure to do so can damage the module. ==\n\n# Info\n\n|Pin# |GPIO|Pin Name   |Description            |   |   |Pin# |GPIO|Pin Name   |Description                      |\n|-----|----|-----------|-----------------------|---|---|-----|----|-----------|---------------------------------|\n|1    |    |3.3V       |                       |   |   |2    |    |5V         |                                 |\n|3    |2   |SDA        |(I2C1)                 |   |   |4    |    |5V         |                                 |\n|5    |3   |SCL        |(I2C1)                 |   |   |6    |    |GND        |                                 |\n|7    |4   |GPSEN      |(GPS) GPS Enable       |   |   |8    |14  |UART TX    |(GPS)RX                          |\n|9    |    |GND        |                       |   |   |10   |15  |UART RX    |(GPS)TX                          |\n|11   |17  |PPS        |(GPS) 1 Sec Pulse      |   |   |12   |18  |FANPWM     |Fan Speed PWM                    |\n|13   |27  |Unused     |                       |   |   |14   |    |GND        |                                 |\n|15   |22  |Unused     |                       |   |   |16   |23  |Unused     |                                 |\n|17   |    |3.3V       |                       |   |   |18   |24  |RST        |(LoRa) Reset                     |\n|19   |10  |MOSI       |(LoRa)                 |   |   |20   |    |GND        |                                 |\n|21   |9   |MISO       |(LoRa)                 |   |   |22   |25  |Unused     |                                 |\n|23   |11  |CLK        |(LoRa)                 |   |   |24   |8   |CS         |(LoRa) Chip Select               |\n|25   |    |GND        |                       |   |   |26   |7   |           |                                 |\n|27   |0   |ID-SDA     |(I2C0) For HAT+ EEPROM |   |   |28   |1   |ID-SCL     |(I2C0) For HAT+ EEPROM           |\n|29   |5   |Unused     |                       |   |   |30   |    |GND        |                                 |\n|31   |6   |Unused     |                       |   |   |32   |12  |RXEN       |(LoRa) Recieve Enable            |\n|33   |13  |Unused     |                       |   |   |34   |    |GND        |                                 |\n|35   |19  |Unused     |                       |   |   |36   |16  |IRQ        |(LoRa)                           |\n|37   |26  |Unused     |                       |   |   |38   |20  |BUSY       |(LoRa)                           |\n|39   |    |GND        |                       |   |   |40   |21  |Unused     |                                 |\n\n\n\n\n\n# Compatibility\n\n| Raspberry Pi Model      | Working? |\n|-------------------------|----------|\n| Raspberry Pi 1 Model A  | Never*   |\n| Raspberry Pi 1 Model A+ | ???      |\n| Raspberry Pi 1 Model B  | Never*   |\n| Raspberry Pi 1 Model B+ | ???      |\n| Raspberry Pi 2 Model B  | Yes      |\n| Raspberry Pi 3 Model B  | Yes      |\n| Raspberry Pi 3 Model B+ | Yes      |\n| Raspberry Pi 3 Model A+ | Yes      |\n| Raspberry Pi 4 Model B  | Yes      |\n| Raspberry Pi 400        | Yes      |\n| Raspberry Pi 5          | Yes      |\n| Raspberry Pi 500        | Yes      |\n| Raspberry Pi Zero       | Yes      |\n| Raspberry Pi Zero W     | Yes      |\n| Raspberry Pi Zero 2 W   | Yes      |\n| Raspberry Pi Pico       | Never*   |\n| Raspberry Pi Pico W     | Never*   |\n\n*Raspberry Pi `1 Model A`, `1 Model B`, and `Pico` do not implement the 40-pin layout used in the MeshAdv Pi Hat.\n\n\n\n# Installing Meshtasticd\n\n~~Watch this video first: [How to install Meshtastic on Raspberry Pi](https://www.youtube.com/watch?v=vLGoEPNT0Mk)~~ This video covers the old method, still a good video but out of date.\n\n\nOfficial installation instructions: [https://meshtastic.org/docs/hardware/devices/linux-native-hardware/]\n\n\n\n# Configuration\n\n==This hat features HAT+ compatibility with an onboard EEPROM for quick setup. This feature is currently experimental==\n\nThese instructions assume you are using a raspberry pi with Raspberry Pi OS. \n\n## New Method:\n\n   - As methods keep changing, please [CLICK HERE](https://meshtastic.org/docs/hardware/devices/linux-native-hardware/#configuration) for the most up to date configuration process\n\n---\n## Old Method:\n\n   - The old method is below and still works if you prefer it\n\n\n```bash\nsudo nano /etc/meshtasticd/config.yaml\n```\nadd or uncomment the following lines as needed.\n\n```yaml\nLora:\n  Module: sx1262  # Ebyte E22-900M22S choose only one module at a time\n# Module: sx1268  # Ebyte E22 400M22S\n  CS: 8  \n  IRQ: 16\n  Busy: 20\n  Reset: 24\n  TXen: 13\n  DIO2_AS_RF_SWITCH: true\n  DIO3_TCXO_VOLTAGE: true\n\nGPS:\n  SerialPath: /dev/ttyS0\n\nI2C:\n  I2CDevice: /dev/i2c-1\n\nLogging:\n  LogLevel: info # debug, info, warn, error\n\nWebserver:\n  Port: 443 # Port for Webserver \u0026 Webservices\n  RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer\n\nGeneral:\n  MaxNodes: 200\n```\n## LoRa Setup:\n\n- You must now set the LoRa Region to be able to start using Meshtastic. [CLICK HERE](https://meshtastic.org/docs/getting-started/initial-config/#set-regional-settings) for info on how to set region settings. Please note: Linux-Native is currently unable to connect over bluetooth or to the Apple app. All other methods are working. \n\n---\n\n# GPS\n   \n   - The ATGM336H-5NR32 can receive the GPS and BeiDou constellations. It is fully integrated into the MeshAdv Mini with the ability to put the GPS to sleep for low power consumption and also utilize the PPS output for very precise time keeping, useful for running an NTP server alongside Meshtastic.\n   - Start by following the official instructions to get the GPS working with meshtasticd [CLICK HERE](https://meshtastic.org/docs/hardware/devices/linux-native-hardware/#uart-raspberry-pi)\n   - ### PPS Time Correction:\n      \u003cdetails\u003e\n      \u003csummary\u003e▶️ Click to Show Instructions\u003c/summary\u003e\n            \n   \n      ## 1. Enable PPS Support in Raspberry Pi OS\n      Edit the `config.txt` file:\n      \n      ```bash\n      sudo nano /boot/config.txt\n      ```\n      \n      Add the following line at the bottom:\n      ```bash\n      dtoverlay=pps-gpio,gpiopin=17\n      ```\n      \n      Save and exit (`CTRL+X`, then `Y`, then `ENTER`).\n      \n      Reboot the Raspberry Pi:\n      ```bash\n      sudo reboot\n      ```\n      \n      ---\n      \n      ## 2. Verify PPS Signal\n      After reboot, check if the **PPS device is detected**:\n      ```bash\n      ls /dev/pps*\n      ```\n      Expected output:\n      ```bash\n      /dev/pps0\n      ```\n      \n      Check if PPS is generating pulses:\n      ```bash\n      sudo ppstest /dev/pps0\n      ```\n      Expected output (timestamps every second):\n      ```\n      trying PPS source \"/dev/pps0\"\n      found PPS source \"/dev/pps0\"\n      ok, found 1 source(s), now start fetching data...\n      source 0 - assert 1672531199.999999999, sequence: 12345 - clear  0.000000000, sequence: 0\n      ```\n      \n      ---\n      \n      ## 3. Sync System Time with PPS\n      Install `pps-tools` and `chrony`:\n      ```bash\n      sudo apt update\n      sudo apt install pps-tools chrony\n      ```\n      \n      Edit the **Chrony config**:\n      ```bash\n      sudo nano /etc/chrony/chrony.conf\n      ```\n      \n      Add the following at the end:\n      ```bash\n      # Use PPS signal for accurate timing\n      refclock PPS /dev/pps0 lock GPS prefer\n      ```\n      \n      Restart Chrony:\n      ```bash\n      sudo systemctl restart chronyd\n      ```\n      \n      Check PPS synchronization:\n      ```bash\n      chronyc sources -v\n      ```\n      Expected output should show PPS as a preferred time source.\n      \n      ---\n   \n      ## 4. (Optional) Sync GPS Time via NMEA\n      If you want **both GPS time and PPS**, modify `chrony.conf` to include:\n      ```bash\n      refclock SHM 0 delay 0.5 refid GPS\n      refclock PPS /dev/pps0 lock GPS prefer\n      ```\n      \u003c/details\u003e\n   \n---  \n   \n# Temp Sensor TMP102\n\n   - The MeshAdv Mini has an onboard Texas Instruments TMP102 temp sensor soldered in the center of the board near the EEPROM to get a general idea of board/enclosure temperature with 0.5°C accuracy. This sensor uses I2C address 48.\n\n\u003cdetails\u003e\n  \u003csummary\u003e▶️ Click to Show Instructions\u003c/summary\u003e\n\n\n---\n\n\n## Step 1: Enable I2C on the Raspberry Pi\n1. Open the Raspberry Pi configuration tool:\n   ```bash\n   sudo raspi-config\n   ```\n2. Go to **\"Interface Options\" \u003e \"I2C\"**, enable it, and exit.\n3. Reboot the Pi to apply changes:\n   ```bash\n   sudo reboot\n   ```\n\n---\n\n## Step 2: Install Required Packages\nUpdate your package list and install **I2C tools** and **Python SMBus**:\n```bash\nsudo apt update\nsudo apt install i2c-tools python3-smbus -y\n```\n\n---\n\n## Step 3: Verify the TMP102 Connection\nFind the **I2C address** of the TMP102 sensor:\n```bash\nsudo i2cdetect -y 1\n```\n- If connected correctly, you should see **0x48** (default address).\n\n---\n\n## Step 4: Create the Python Script\n1. Open a new script file:\n   ```bash\n   sudo nano tmp102.py\n   ```\n\n2. Paste the following Python code:\n   ```python\n   #!/usr/bin/env python3\n   import smbus\n   import time\n\n   # I2C setup\n   bus = smbus.SMBus(1)  # Use I2C bus 1\n   TMP102_ADDR = 0x48  # Default I2C address for TMP102\n\n   def read_temp():\n       \"\"\"Reads temperature from TMP102 and converts it to Celsius\"\"\"\n       raw = bus.read_word_data(TMP102_ADDR, 0)\n       \n       # Swap byte order (TMP102 stores in little-endian)\n       raw = ((raw \u003c\u003c 8) \u0026 0xFF00) + (raw \u003e\u003e 8)\n       \n       # Convert to temperature (TMP102 uses 12-bit resolution)\n       temp_c = (raw \u003e\u003e 4) * 0.0625\n       return temp_c\n\n   if __name__ == \"__main__\":\n       while True:\n           print(f\"Temperature: {read_temp():.2f}°C\")\n           time.sleep(1)\n   ```\n\n3. Save and exit (`CTRL+X`, then `Y`, then `Enter`).\n\n---\n\n## Step 5: Make the Script Executable\nRun this command to **make the script executable**:\n```bash\nsudo chmod +x tmp102.py\n```\n\n---\n\n## Step 6: Run the Script\nNow, you can run the script in **two ways**:\n\n1️⃣ **Using Python**:\n   ```bash\n   python3 tmp102.py\n   ```\n\n2️⃣ **Directly from CLI** (since we added a shebang and made it executable):\n   ```bash\n   ./tmp102.py\n   ```\n\n\n---\n\n## ✅ You're All Set!\nNow your **Raspberry Pi** reads temperature from the **TMP102 sensor** and prints it to the console! 🎉\n\n🚀\n\u003c/details\u003e\n\n\n---\n\n# PWM Fan\n\n   - The onboard PWM fan connector can support 2 wire 5V fans (Always on), and 4-pin PWM (Tach not implemented). I recommend the [Noctua NF-A4x10 5V PWM 40mm](https://a.co/d/4vufchq) 0r [Noctua NF-A8 5V PWM 80mm](https://a.co/d/56CNeq1)\n\n   - Setup:   \n      \u003cdetails\u003e\n        \u003csummary\u003e▶️ Click to Show Instructions\u003c/summary\u003e\n      \n        ---\n      \n      \n      ## Option 1: (Easiest - Works with Pi 4 and 5 only) Use the built-in fan control tool to turn fan on and off\n      \n      1. Open the `raspi-config` tool by running the following:\n         ```bash\n         sudo raspi-config\n         ```\n      2. Navigate to the \"Performance Options\" section.\n      3. Select \"Fan\" and enable the fan control.\n      4. Set the GPIO pin to 18 and temperature threshold for the fan to start. By default, the fan starts at 60°C, but you can modify this by editing the `/boot/firmware/config.txt` file manually.\n         ```bash\n         sudo nano /boot/firmware/config.txt\n         ```\n         add the following:\n         ```bash\n         dtoverlay=gpio-fan,gpiopin=18,temp=60000\n         ```\n      6. Exit and reboot\n      \n         ---\n      \n      ## Option 2 (works for most Pi models)\n      \n      1. Install the `Rpi.GPIO` Python library\n         ```bash\n         sudo apt update \u0026\u0026 sudo apt install python3-rpi.gpio\n         ```\n      2. Create a new file called `fan_control.py`\n         ```bash\n         sudo nano fan_control.py\n         ```\n      3. Copy the following and save the file:\n         ```bash\n         #!/usr/bin/env python3\n         import RPi.GPIO as GPIO\n         import time\n      \n         # Configuration\n         FAN_PIN = 18\n         TEMP_THRESHOLD_LOW = 45.0  # Temperature (°C) at which fan runs at minimum speed\n         TEMP_THRESHOLD_HIGH = 60.0  # Temperature (°C) at which fan runs at max speed\n      \n         # Initialize GPIO\n         GPIO.setmode(GPIO.BCM)\n         GPIO.setup(FAN_PIN, GPIO.OUT)\n         pwm = GPIO.PWM(FAN_PIN, 25000)  # 25 kHz PWM frequency\n         pwm.start(0)  # Start with fan off\n      \n         def get_cpu_temp():\n             \"\"\"Reads the CPU temperature.\"\"\"\n             with open(\"/sys/class/thermal/thermal_zone0/temp\", \"r\") as f:\n                 return int(f.read()) / 1000  # Convert from millidegrees to degrees\n      \n         def set_fan_speed(temp):\n             \"\"\"Adjusts fan speed based on temperature.\"\"\"\n             if temp \u003c TEMP_THRESHOLD_LOW:\n                 duty_cycle = 0  # Fan off\n             elif temp \u003e TEMP_THRESHOLD_HIGH:\n                 duty_cycle = 100  # Full speed\n             else:\n                 # Scale between min and max speed\n                 duty_cycle = (temp - TEMP_THRESHOLD_LOW) / (TEMP_THRESHOLD_HIGH - TEMP_THRESHOLD_LOW) * 100\n             pwm.ChangeDutyCycle(duty_cycle)\n      \n         try:\n             while True:\n                 temp = get_cpu_temp()\n                 set_fan_speed(temp)\n                 print(f\"CPU Temp: {temp:.1f}°C | Fan Speed: {int(pwm.ChangeDutyCycle)}%\")\n                 time.sleep(5)  # Check every 5 seconds\n         except KeyboardInterrupt:\n             print(\"Fan control stopped\")\n             pwm.stop()\n             GPIO.cleanup()\n         ```\n      4. Make the file executable\n         ```bash\n         chmod +x fan_control.py\n         ```\n      5. Optional: Run script at boot\n         ```bash\n         crontab -e\n         ```\n         Add this line at the end:\n         ```bash\n         @reboot /usr/bin/python3 /path/to/fan_control.py \u0026\n         ```\n         Hint: use pwd command to find your current directory. Change \"/path/to\" the location of your script.\n      \n      \n      \n      \u003c/details\u003e\n      \n      |Pin|Name    |Color |\n      |---|--------|------|\n      |1  |Ground  |Black |\n      |2  |5V      |Yellow|\n      |3  |NC      |Green |\n      |4  |PWM     |Blue  |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrismyers2000%2Fmeshadv-mini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrismyers2000%2Fmeshadv-mini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrismyers2000%2Fmeshadv-mini/lists"}