Issue Migrating RadioHead ASK Receiver from Arduino IDE to PlatformIO

I have an ATtiny85 sketch I need to maintain.
I want to do this using PlatformIO rather than Arduino IDE.
I have prepared a sample sketch and circuit - below
I can compile and upload sketch both on PlatformIO and Arduino IDE - as in - straight copy and paste.
If I use Arduino IDE, the received character is decoded and the LED blinks. If I compile and upload using PlatformIO, the character is never received.
I am using the same physical Aurduino Uno as ISP so do not change anything physical between these two test scenarios.
The RH library I am using is the TinyHead version - a stripped down version so it fits in an ATtiny85 with room to spare for a program.

My sample code

/*
 * ATtiny85RX.cpp
 *
 * Created: 10/06/2022 10:26:02
 * Author : Peter

A simple example of a receiver. Taken from the original RadioHead library.
All credits and free beer to: https://www.airspayce.com/mikem/arduino/RadioHead/
this uses the TinyHead library which is a stripped down version of the original RadioHead 1.121 library
Downloaded from <http://sparwcreations.com/arduino/TinyHead/TinyHead.zip>
The library takes over Timer0 and needs the MCU to be at 8MHz 
 
 * Target : Board: ATtiny25/45/85 Processor: ATtiny85 CLock: Internal 8MHz

 * Fuse setting: Brown-out detection at VCC =  1.8 V
 
 */ 

 
#ifndef F_CPU
#define F_CPU 8000000UL    // TinyHead needs it to be 8MHz
#endif

#include <avr/io.h>       // pulls in (most of) the register and register bit names
#include <avr/common.h>   // added so SREG is a recognized register name - seems to be mission from <avr/io.h>
#include <util/delay.h>   // needed for the delay functions
#include <Arduino.h>
#include <RH_ASK.h>

#define LED PB0 // PIR power output
#define RXD PB1 // data from RH_ASK receiver

#define RADIOHEAD_BAUD 2000     // Transmission Speed
#define RADIOHEAD_TX_PIN -1     // Pin of the 433MHz transmitter
#define RADIOHEAD_RX_PIN RXD    // Pin of the 433MHz receiver 

RH_ASK driver(RADIOHEAD_BAUD, RADIOHEAD_RX_PIN, RADIOHEAD_TX_PIN);

// Pin definitions and use
/*                  ATtiny85
        PCINT5/-RESET/ACD0/dw PB5 1| u |8 VCC
 PCINT3/XTAL1/CLKI/-OC1B/ADC3 PB3 2|   |7 PB2 SCK/USCK/SCL/ADC1/T0/INT0/PCINT2
  PCINT4/XTAL2/CLKO/OC1B/ADC2 PB4 3|   |6 PB1 MISO/DO/AIN1/OC0B/OC1A/PCINT1 (TinyHead RX)
                              GND 4|___|5 PB0 MOSI/DI/SDA/AIN0/OC0A/-OC1A/AREF/PCINT0 (LED)

 PB0 - LED - output for LED
 PB1 - RXD - Reserved for TinyHead RX
 
 */  
  
void bip(void){                 // used to feed back key moments in program
  PORTB ^= (1<<LED);
  _delay_ms(50);
  PORTB ^= (1<<LED);
  _delay_ms(50);
}

void setup() {
  // put your setup code here, to run once:

  DDRB |= (1<<LED);         // define outputs
  PORTB |= (1<<RXD);        // set internal pull ups
  PORTB &= ~(1<<LED);       // shut down PWR
    
  driver.init();            // radio head driver
}

void loop() {
  // put your main code here, to run repeatedly:
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);
  
    if (driver.recv(buf, &buflen)) {  // Message with a good checksum received
      if (((char) buf[0]) == 0x4D){   // the transmitter has issued an "M" character
        bip();                        // debug flash to confirm receipt
      }
    }
}

My circuit

My platformio.ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:attiny85]
platform = atmelavr
board = attiny85
framework = arduino

; device is USBASP V2.0 with updated firmware
;upload_protocol = custom
;upload_port = usb
;upload_flags =
;    -C
;    ; use "tool-avrdude-megaavr" for the atmelmegaavr platform
;    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
;    -p
;    $BOARD_MCU
;    -P
;    $UPLOAD_PORT
;    -c
;    usbasp
;upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

; device is program_via_ArduinoISP
upload_protocol = custom
upload_port = COM8
upload_speed = 19200
upload_flags =
    -C
    ; use "tool-avrdude-megaavr" for the atmelmegaavr platform
    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
    -p
    $BOARD_MCU
    -P
    $UPLOAD_PORT
    -b
    $UPLOAD_SPEED
    -c
    stk500v1
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

; device is a Pololu USB AVR programmer
;upload_protocol = custom
;upload_port = COM5
;upload_speed = 19200
;upload_flags =
;    -C
;    ; use "tool-avrdude-megaavr" for the atmelmegaavr platform
;    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
;   -p
;    $BOARD_MCU
;    -P
;    $UPLOAD_PORT
;    ;-b
;    ;$UPLOAD_SPEED
;    -c
;    stk500v2
;upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

You can see I have variously used different programmers - but they all give similar results.

A picture showing my lib section to show RH libraries
Lib

And finally the Upload terminal output - note the warnings from the library

 *  Executing task in folder ATtiny85_RH_test: C:\Users\Peter\.platformio\penv\Scripts\platformio.exe run --target upload 

Processing attiny85 (platform: atmelavr; board: attiny85; framework: arduino)
-----------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/attiny85.html
PLATFORM: Atmel AVR (3.4.0) > Generic ATtiny85
HARDWARE: ATTINY85 8MHz, 512B RAM, 8KB Flash
DEBUG: Current (simavr) On-board (simavr)
PACKAGES:
 - framework-arduino-avr-attiny @ 1.5.2
 - tool-avrdude @ 1.60300.200527 (6.3.0)
 - toolchain-atmelavr @ 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 10 compatible libraries
Scanning dependencies...
Dependency Graph
|-- TinyHead
|   |-- SPI @ 2.0.0
Building in release mode
Compiling .pio\build\attiny85\src\main.cpp.o
In file included from lib\TinyHead/RHGenericDriver.h:9:0,
                 from lib\TinyHead/RH_ASK.h:9,
                 from src\main.cpp:28:
lib\TinyHead/RadioHead.h:1129:4: warning: #warning Arduino TinyCore does not support hardware SPI. Use software SPI instead. [-Wcpp]
   #warning Arduino TinyCore does not support hardware SPI. Use software SPI instead.
    ^~~~~~~
Linking .pio\build\attiny85\firmware.elf
Checking size .pio\build\attiny85\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=======   ]  68.2% (used 349 bytes from 512 bytes)
Flash: [=====     ]  51.6% (used 4230 bytes from 8192 bytes)
Building .pio\build\attiny85\firmware.hex
Configuring upload protocol...
AVAILABLE: custom
CURRENT: upload_protocol = custom
Uploading .pio\build\attiny85\firmware.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b (probably t85)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file ".pio\build\attiny85\firmware.hex"
avrdude: writing flash (4230 bytes):

Writing | ################################################## | 100% 6.04s

avrdude: 4230 bytes of flash written
avrdude: verifying flash memory against .pio\build\attiny85\firmware.hex:
avrdude: load data flash data from input file .pio\build\attiny85\firmware.hex:
avrdude: input file .pio\build\attiny85\firmware.hex contains 4230 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 3.02s

avrdude: verifying ...
avrdude: 4230 bytes of flash verified

avrdude: safemode: Fuses OK (E:FE, H:DE, L:E2)

avrdude done.  Thank you.

================================ [SUCCESS] Took 14.28 seconds ================================
 *  Terminal will be reused by tasks, press any key to close it. 

I think it may be something to do with how Arduino framework handles clock speeds but I am a newbie.

When the unit is not receiving any transmission, there is a ‘background’ square wave at PB1 - I thought this was just noise being coded. But the frequency of this seems to vary depending on whether I’ve just used Arduino IDE or PlatformIO to upload (with Arduino Uno as ISP still attached) or whether the ISP cable is removed and ATtiny85 is powered from another 5v supply.

With the Arduino IDE loaded version, it works whether the ISP cable is left attached to the Arduino as ISP or disconnected with external 5v supply

Do you have any ideas as to what is going on?

I tried adding pull ups to all the unused ports as in

 PORTB |= (1<<RXD)|(1<<PB2)|(1<<PB3)|(1<<PB4);        // set internal pull ups

but it made no difference

In the Arduino IDE, do you have the “2.0.0-dev” version of the ATTiny core installed or the 1.5.2 version? (Version is in the Tools->Board->Board Manager)

Hi Max
In Arduino IDE, I have attiny by David A Mellis version 1.0.2 but I also have ATtinyCore by Spence Konde at version 1.5.2

I was experimenting in Arduino and the one that I had success with was the attiny version by David A Mellis.

I am also looking at the comments in the library "The library takes over Timer0 and needs the MCU to be at 8MHz ".

I note that _delay_ms() also uses Timer0 so I’m looking at removing these sections of code to see if that makes a difference.

I’m struggling to get anything to work now even using Arduino IDE even though yesterday I had reproduceable results - hence this post.
Maybe I should dump the ATtiny85 altogether - I have a ‘control’ receiver running on a Nano and that works consistently OK but it’s on a mains derived supply and I wanted to use ATtiny85 so I could run completed build on batteries.
As a first step, I’ll run up another Nano receiver and test the actual 433MHz receiver module is doing it’s job.

But PlatformIO is using

So it’s not using the same core at all. PlatformIO doesn’t have support for GitHub - damellis/attiny: ATtiny microcontroller support for the Arduino IDE.

Hi Max
Many thanks - well that sort of knocks that on the head then.

I’ve been struggling to get anything to work now on the ATtiny85 even in Arduino land. I suspect it might have something to do with the internal RC oscillator not being as spot on as the externally crystal clocked other (successful) board attempts.

I’ve loaded the RH_ASK library onto an Arduino Nano clone (ATmega168P). This works a treat in Arduino land but I’m currently struggling to do an upload from within PlatformIO - it claims the device is am ATmega168P - yup I get than from the writing on the chip. Just hunting round for a PlatformIO board that matches what I’ve got.

avrdude: Device signature = 0x1e940b (probably m168p)
avrdude: Expected signature for ATmega168 is 1E 94 06
         Double check chip, or use -F to override this check.

avrdude done.  Thank you.

*** [upload] Error 1

I suspect I should close this thread as the Nano is not the target board - too much stuff on it for a battery powered target build. I only started down this track to test my RF receiver and then as a side interest, to see if I could port a ‘Nano’ program I had from Arduino to PlatformIO.

My migration task (Arduino IDE to PlatformIO) is not all plain sailing.

By the way how might I use the F switch to override the device ID check? (I checked the device ID using Studio7 and it agreed device is returning an ID of 0x1e940b)

But a ATMega168P and ATMega168P might be different chips. Maybe PlatformIO has a bug here, it declares for board = /nanoatmega168

You may try and fix this by going into your local C:\Users\<user>\.platformio\platforms\atmelavr\boards\nanoatmega168.json file and changing the mcu field to atmega168p.

I succeeded in Upload onto my Nano by just claiming it was an ATmega168P - see platformio.ini extract below


[env:ATmega168P]
platform = atmelavr
board = ATmega168P
framework = arduino

Import worked a dream

*  Executing task in folder Nano_test: C:\Users\Peter\.platformio\penv\Scripts\platformio.exe run --target upload 

Processing ATmega168P (platform: atmelavr; board: ATmega168P; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/ATmega168P.html
PLATFORM: Atmel AVR (3.4.0) > ATmega168P/PA    
HARDWARE: ATMEGA168P 16MHz, 1KB RAM, 16KB Flash
DEBUG: Current (simavr) On-board (simavr)      
PACKAGES:
 - framework-arduino-avr-minicore @ 2.1.3      
 - tool-avrdude @ 1.60300.200527 (6.3.0)       
 - toolchain-atmelavr @ 1.70300.191015 (7.3.0) 
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 9 compatible libraries
Scanning dependencies...
Dependency Graph
|-- TinyHead
|   |-- SPI @ 1.0
Building in release mode
Checking size .pio\build\ATmega168P\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=====     ]  52.5% (used 538 bytes from 1024 bytes)
Flash: [====      ]  43.8% (used 6952 bytes from 15872 bytes)
Configuring upload protocol...
AVAILABLE: custom
CURRENT: upload_protocol = custom
Uploading .pio\build\ATmega168P\firmware.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e940b (probably m168p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file ".pio\build\ATmega168P\firmware.hex"
avrdude: writing flash (6952 bytes):

Writing | ################################################## | 100% 7.66s

avrdude: 6952 bytes of flash written
avrdude: verifying flash memory against .pio\build\ATmega168P\firmware.hex:
avrdude: load data flash data from input file .pio\build\ATmega168P\firmware.hex:
avrdude: input file .pio\build\ATmega168P\firmware.hex contains 6952 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 4.28s

avrdude: verifying ...
avrdude: 6952 bytes of flash verified

avrdude: safemode: Fuses OK (E:F8, H:DD, L:FF)

avrdude done.  Thank you.

=============================================== [SUCCESS] Took 16.21 seconds =============================================== *  Terminal will be reused by tasks, press any key to close it. 

But does it work with my RF unit? - yeah! it does. I’m going to have a go with a Pro Mini next - not so much onboard stuff to power with a battery.

Thanks for all your help. I’m going to flag this as ‘solution’ and conclude that ATtiny85 are not the best MCU to work with the RH_ASK library.

Regards uploading to a Pro Mini (3v 8MHz)
I managed two methods…
First using a 6 pin Serial to TTY convertor board. I struggled for a while with platformio.ini but here is eventual setting - it even auto found com port…

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:pro8MHzatmega328]
platform = atmelavr
board = pro8MHzatmega328
framework = arduino

The wiring of the TTY took some care - see photo


If you look closely at the Serial to TTY connector, you can see the 6 way connector is split into 2x3way. If you reverse connector at the top (as in photo) you get to connect 5v to the Pro Mini in place of 3.3v.

Then I tried using my Pololu USB AVR Programmer - this has a config app that lets you define some pins - the upshot is you can control the VCC to board with this config tool - it lets you define a pin for the DTR signal. See the neat connection and the config required below:



Ooh - it’s almost getting fun.
Time to finally close this post (and in passing - to split infinitives where no one has split them before).