Arduino IDE Compile Error

Software: Arduino IDE version 2.3.5

Hardware: ATtiny84, HW-740 (AM-312) PIR sensor, and DY-SV5W-3 MP3 player

Issue: I have a simple sketch that detects motion from the PIR, starts the MP3 player and illuminates LEDs. The sketch works fine and compiles using an Uno but when I port the sketch over to the tiny84, I am getting a compiler error from DYPlayerArduino.h library file. I was able to successfully upload a simple blink program to the 84 to verify operation.

Here is the error:

In file included from C:\Users\dmace\OneDrive\Documents\Arduino\Skull_Test5\Skull_Test5.ino:3:0:
c:\Users\dmace\OneDrive\Documents\Arduino\libraries\DYPlayer\src/DYPlayerArduino.h:31:27: error: expected ')' before '*' token
Player(HardwareSerial *port);

I am using ATTinyCore by Konde, the dyplayer library by SnidjerC (dyplayer/src/DYPlayerArduino.cpp at main · SnijderC/dyplayer · GitHub), the DY-SV5W-3 data sheet can be viewed here: https://digitaltown.co.uk/images/components/DYSV5W/DY-SV5W%20Voice%20Playback%20ModuleDatasheet.pdf

Since it is port related, my gut tells me it may be a hardware abstraction layer (HAL) issue but I am way out of my element on this. Here is my code for the sketch:

#include <SoftwareSerial.h>

#include "DYPlayerArduino.h"

const byte PIR_PIN = 0;
const byte rxPin = 2;
const byte txPin = 3;

const unsigned long debounceDelay = 1000; // 1 second debounce
const unsigned long cooldownPeriod = 7000;
unsigned long lastMotionTime = 0;
unsigned long lastCooldownTime = 0;
bool inCooldown = false;

byte motionStatus = 0;
byte pirState = 0;
byte track = 1;

SoftwareSerial fxSerial(rxPin, txPin);
DY::Player player(&fxSerial);

void setup() {
  pinMode(PIR_PIN, INPUT);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  Serial.begin(9600);
  fxSerial.begin(9600);
  player.setVolume(30);

  delay(3000);
}

void loop() {
  motionStatus = digitalRead(PIR_PIN);

  unsigned long currentTime = millis();

  if (motionStatus == HIGH && !inCooldown && (currentTime - lastMotionTime > debounceDelay)) {
    lastMotionTime = currentTime;

      Serial.println("Motion Detected");
      pirState = HIGH;
      byte soundCount = player.getSoundCount();
      track = random(1, soundCount);
      player.playSpecified(track);

      lastCooldownTime = currentTime;
      inCooldown = true;
  }

  //else {

    if (motionStatus == LOW && pirState == HIGH) {
      Serial.println("Motion Ended");
      pirState = LOW;
    }
  //}
  if (inCooldown && (currentTime - lastCooldownTime > cooldownPeriod)) {
    inCooldown = false;
  }
}

Not looking for a solution but some encouragement and guidance on how I should proceed.

Thank you,

Doug

My first guess is the library is not designed for that hardware. Check github and library.properties.

I would see what @DrAzzy has to say on the matter, he is the ATtiny guru after all (and the maintainer of the core if i am not mistaken)

Excerpted from DYPlayerArduino.h:

#ifdef __has_include
#if __has_include("HardwareSerial.h")
#define HAS_HARDWARE_SERIAL
#endif
#endif
.
.
.
#ifdef HAS_HARDWARE_SERIAL
      Player(HardwareSerial *port);
#endif

The DYPlayer library is assuming that if the header file HardwareSerial.h exists in the currently selected core, then all boards supported by that core have a hardware USART.

I'd say you just showed that assumption to be incorrect, as the ATtiny84 does not, to the best of my knowledge, have a hardware USART. Therefore HardwareSerial does not define a class or datatype of any kind.

A better test might be to follow the lead from HardwareSerial.h and test for the existence of one of the USART baud rate registers (UBRRH, UBRR0H, UBRR1H, etc.).

In that case commenting that section of the library out (and out in the .h file) should get rid of that error, but there is also a reference to Serial in the main sketch, which should probably be the next error that shows up. Chances are the ATtiny84 is not the best choice for this project.

Yes, it would. But if it were me, six months later I'd be left scratching my head why the library didn't work when I tried it on a board with a USART, until I finally went "oh yeah, I did that".

That's a perfectly reasonable assumption. Much to my surprise, once I replaced the header check in the library header with the UBRRxH check, the sketch compiled just fine. After a bit of digging I discovered that there is a TinySoftwareSerial instance manifesting as Serial on pins 1 and 2 (dig into the pins_arduino.h file for the ATtiny84 variant and you'll see that SoftwareSerial is enabled by default it seems). Unfortunately that conflicts with the rxPin defined for the SoftwareSerial instance in the sketch. One step forward, two steps back.

I would agree wholeheartedly!

I used the TinyDebug library.

Well just that for initial testing, then a rename for that specific version etc.

Though the registers are only named that for Atmel boards, so you may be left scratching your head again when switching to a completely different board.

yeah. There is no HardwareSerial on a tiny84.

One of the newer ATtiny chips should work much better (say, an ATtiny814, using the MegaTinyCore.) (still, it's only got 1 HardwareSerial.)

@sonofcy @Deva_Rishi @van_der_decken @westfw

First and foremost, thank you for taking time to respond. Your comments actually were very helpful and made me go back and read more on the documentation.

I must also say that I am stubborn and so walked the project back using what could be called baby steps. First was to make sure that the programmer was responding correctly by writing a blink sketch and that was good. Second was to wire the PIR in with the LED and make it light in response to motion and that was also good. Third step involved more research into the ATtinycore and taking a look at TinySoftSerial. Using this library and using a TX only PIN, I have successfully gotten the MP3 player to play a sound using the example code here and modifying it for the Tiny84 - Digital Town - DY-SV5W MP3 Player

My biggest concern at this point is the current draw in the circuit. Using a DC power supply set to 5V and .040A, when the circuit is live it is drawing about 18mA and when the PIR kicks the MP3 player, it spikes to about 45/50mA. The only output pin is for the MP3 player that goes to a 1K/2K voltage divider to bring the 5V down to 3.3V which is the players input requirement. It does work after a fashion but only plays one sound and sometimes just keeps repeating the same one over and over without tripping the PIR. The LEDs are supposed to use the Busy pin of the MP3 to light up while playing and go off when idle. Obviously more work to do and will need to concentrate on the functions to create the play command and send the data over serial. Why am I doing this? I won’t learn if I don’t stress myself and make an attempt to make it work. Also, I am doing this one for a Halloween project that I would like to get as small as possible and, in the end, if it isn’t successful, I will cut my losses and use a board with hardware serial.

In the picture, the breadboard circuit is on the left and my Arduino as ISP is on the right.

Not real sure what your point is in post 10 but numerous posts have pointed out what the problem is and some alternatives. In any case I have nothing more.

You can do this with input pins but not with output pins. This is because the attenuation you get will depend on the current, and as this current changes so will the attenuation.

This could damage your Arduino, or anything connected to it.

Also big blocks of text are hard to read, try having a new paragraph every four to five lines maximum.

Well that is searching for the limit.

The player is the 3.3v device, so i guess that should work. Pretty sure you can also just power the ATtiny with 3.3v which would make that divider redundant and should save you some power, though a milliamp or 2 is all that i would expect. I would get a slightly bigger PSU 40mA is really tiny, and it's a fair size box for providing so little.

@Grumpy_Mike @Deva_Rishi

Gents,

My apologies on being wordy and not explaining things a bit more clearly.

The MP3 board uses 5V for input power but only 3.3V on the IO input to trigger a sound. Here is an image of the MP3 that will hopefully clarify that issue.

As far as the power supply, I have the current set lower and yes, it is a variable DC power supply so I can increase the current as needed, I was just being cautious.

@Grumpy_Mike - getting back to your statement on the voltage divider, thank you, I will make that adjustment. Do you recommend using a regulator or as some have suggested, drop tis and use a different MCU?

Yes, I strongly recommend a regulator to drop anything involving a peak current. Even a current limited bench power supply can sometimes be not fast enough to cope with fast transients.

The other alternative is to use a level shifter of the type designed for shifting I2C levels. However, these may not be able to supply enough current for what you want.