ArduinoIDE + Pro Trinket + DFPlayerMini + 20W stereo amp + Laser

I am requesting assistance writing code for my first project that requires integration of several boards using a few different communications methods.

I have added a picture of what I believe is a completed workable prototype. I have never completed a project of this complexity and am unsure how to meld all technologies together. I have done some extensive research gathering all data sheets along with sample codes to run each board individually.

Theory of operation:
Using Arduino IDE format on a Pro Trinket

  1. I use 4 PWM signal wires along with a ground from a RC reciever. Each signal is generated from 4 switches on a RC radio transmitter capable of generating up to 3 PWM signals per switch.

  2. I hook up the four PWM signals using pulseIn() function to pins A0-A3 on a Pro Trinket and assigned them ch1-ch4. (I have recorded PWM ranges that an Arduino Uno read and then displayed for each of ch1-ch4 already)

  3. I need one channel (ch1?) to toggle a relay on/off by sending a high/low signal to a Sunflounder 5V coil relay to operate a 12VDC laser. The signal wire from the relay is hooked up to digital pin 4. Two PWMs required for this channel from RC radio.

  4. I need one channel (ch2-ch4?) to adjust the volume level of the amp board. 3 position switch 1. Switch Low = PWM 0000 = Pro Trinket to attach ground to mute pin on amp board. Mute pin is attached to pin 3 on Pro Trinket. 2. Switch Med = PWM 1500 = Pro Trinket to send a i2c data signal to amp board to set volume at 30. 3. Switch High PWM 2500 = send i2c signal set volume at 60.

  5. I need one channel to change between 3 different audio files on a FDPlayerMini. This is a serial UART tx/rx signal hooked up to the appropriate tx/rx pins on both Pro Trinket and DFPlayerMini. 3 Position switch with 3 PWM signals.

  6. I need one more channel to send an another tx/rx signal from Pro Trinket to DFPlayerMini to “repeat last audio track”. Two position switch (spring loaded normally off) two PWM signals. Switch hooked to spring returns to low position after every manipulation (like a trigger). Low = no action. High = repeat last track.

I believe I have the hardware selected to accommodate these necessary tasks.

I believe the wiring and power is appropriate.

I have run individual codes testing functions to each board and confirmed audio plays and is in proper formats and file orders.

I have succeeded in reading PWM amounts from RC switches to reciever to an Arduino IDE Uno and recorded values to use for code writing.

I don’t, however, know how to write a code that works in harmony with all boards and options required. I’m not sure about what libraries to include? Not sure how to initiate multiple communications types like i2c & UART tx/rx & PWM. I’m not sure the order things should be “int” in the code.

Is there anyone out there that can assist me in competing my first whole project? I don’t mind doing the research and the leg work but I’m lost on how to construct.

Thank you very much for any help at all!!

Right now I will be looking up the actual data command strings needed to be sent for each needed function and will post as soon as I record them from the data sheets.

Any other info I can add that will be helpful?

Thanks!!!

20181210_002928.jpg

  1. I need one channel (ch1?) to toggle a relay on/off by sending a high/low signal to a Sunflounder 5V coil relay to operate a 12VDC laser. The signal wire from the relay is hooked up to digital pin 4. Two PWMs required for this channel from RC radio.

I don't understand that last sentence. The Arduino can send PWM on only a few pins. It can READ PWM signals on ANY pin. You should most likely NOT be PWMing a relay.

  1. I need one channel (ch2-ch4?) to adjust the volume level of the amp board. 3 position switch 1. Switch Low = PWM 0000 = Pro Trinket to attach ground to mute pin on amp board. Mute pin is attached to pin 3 on Pro Trinket. 2. Switch Med = PWM 1500 = Pro Trinket to send a i2c data signal to amp board to set volume at 30. 3. Switch High PWM 2500 = send i2c signal set volume at 60.

Again, this makes little sense. It is extremely unlikely that you will read times of exactly 0, 1500, or 2500 from the appropriate pin. You need to think in terms of ranges. If the time is less than n1, set the pin LOW. If the time is greater than n2 but less than n3, send the appropriate VALUE to the I2C slave. If the value is greater than n3, send the (other) appropriate VALUE to the I2C slave.

I'm not sure about what libraries to include?

Is that a statement or a question? If it is a question, as indicated by the punctuation, why would you be asking us what you are sure about?

If it is a statement, it's a bit hard to accept, given that you have written, or so you said, code to test all the pieces individually. You KNOW what libraries are needed for each of those sketches.

Thanks PaulS for the quick response!

I'll go through each response and try and explain the best that I can. I am still really new so I'm sure a lot of my lingo is lacking.

To the first.

"PWMing a relay". Maybe that description was wrong? This is an Arduino compatible relay (5V coil) that will handle the amperage/voltage of my laser module. I saw a simple code that stated that a "High" or a "low" signal is sent the relay module. Perhaps the signal is not in the form of a PWM?

To the second.

You are right. I just posted for example but was not sure how to code with a PWM "range". Some of the PWM readouts I recorded are Switch down 1053-1054 switch center 1484-1490 switch up 1938-1945.

Hum? So can I code to look for a range like 1040-1060 & 1470-1500 & 1930-1950?

And if I gathered properly receiving the n1 (PWM 0000 in my example) PWM signal the Arduino would send a "Low" signal to arduino pin which then attaches ground to amp board mute pin? Gound to mute pin on amp board = mute.

I am also gathering the Pro Trinket would be the master and the amp board would be the slave in the i2c bus.

And for the third.

So when I posted "I am unsure which libraries to include?"
What I tried to explain is I'm not sure how to write a sketch from beginning to completion.
What I have done is tested only certain functions of boards individually. Like a copy and paste. A lot of functions I have not tested. I also have not copied and pasted a sketch that included more than one form of communication.
So actually I don't know what libraries to include. I could go back through all the individual copied and pasted sketches and record all used libraries? I'm not sure that it would include all libraries needed to complete functions I have not tested yet.

Thanks a million!

“PWMing a relay”. Maybe that description was wrong? This is an Arduino compatible relay (5V coil) that will handle the amperage/voltage of my laser module. I saw a simple code that stated that a “High” or a “low” signal is sent the relay module. Perhaps the signal is not in the form of a PWM?

PWM turns a pin on and off, very rapidly. For some devices, like LEDs and motors, this appears to create a lower voltage output, so the LED is dimmer or the motor is slower. Turning a mechanical relay on an off that frequently will cause damage to the relay.

Hum? So can I code to look for a range like 1040-1060 & 1470-1500 & 1930-1950?

unsigned long time = pulseIn(somePin, someState);
if(time >= 1040 && time <= 1060)
{
   doLow();
}
else if(time >= 1470 && time <= 1500)
{
   doMedium();
}
else if(time >= 1930 && time <= 1950)
{
   doHigh();
}

When I am unsure how to write a new program, I start with a basic starter program. For the Arduino, that would be:

void setup()
{
}

void loop()
{
}

Then, I write comments explaining what the code should do.

void loop()
{
   // read RC inputs

   // deal with channel 1 value
   // deal with channel 2 value
   // deal with channel 3 value
   // deal with channel 4 value
}

Then, I add a function call. to a non-existent function to implement each comment, one at a time.

void loop()
{
   // read RC inputs
   readRCData();

   // deal with channel 1 value
   // deal with channel 2 value
   // deal with channel 3 value
   // deal with channel 4 value
}

Then, I develop the function. Obviously, the function can’t return 4 values, for the 4 channels, so there need to be global variables to store the data in. The pins that it uses should not be hardcoded in the function, so you need global variables to hold them. The pins need to be in the correct mode, so you have to add code to setup() to make sure that they are.

When I add code that fails to compile (and I test that every 10 lines or so), then I examine why. Am I trying to call a function incorrectly? Am I trying to use a library that I have not included? Am I trying to use a variable that has not been initialized properly? Whatever the problem, I can resolve it pretty quickly, because I understand the code that I have written (and tested) so far, and I understand what I am trying to accomplish.

You can do the same thing.

Thanks Paul's I'll follow your instruction.

Ok I moved project over to my Arduino Uno so I can watch the serial monitor.

Next I'll retype my sketch that I have so far but I'm not sure how to post sketch properly.

int ch1;
int ch2;
int ch3;
int ch4;

void setup()  {

  pinMode (4, INPUT) ;
  pinMode (5, INPUT) ;
  pinMode (6, INPUT) ;
  pinMode (7, INPUT) ;

  Serial.begin(9600) ;

}

void loop () {

  ch1 = pulseIn(4, HIGH, 25000) ;
  ch2 = pulseIn(5, HIGH, 25000) ;
  ch3 = pulseIn(6, HIGH, 25000) ;
  ch4 = pluseIn(7, HIGH, 25000) ;

  Serial.print("Channel 1: ") ;
  Serial.println(ch1) ;

  Serial.print("Channel 2: ") ;
  Serial.println(ch2) ;

  Serial.print("Channel 3: ") ;
  Serial.println(ch3) ;

  Serial.print("Channel 4: ") ;
  Serial.println(ch4) ;

  delay(1000) ;

}

When I was looking over your advice I saw a line in the sketch----->"readRCData();".

Hum....? Where can I find these available commands to utilize?

I am looking up now the function of that command in Arduino.cc right now.

Here is a sample sketch I found for the Sunfounder Arduino relay module.

/**********************************************/
const int relayPin =6; //the "s" of relay module attach to
/**********************************************/
void setup()
{
pinMode(relayPin, OUTPUT); //initialize relay as an output
}
/***********************************************/
void loop()
{
digitalWrite(relayPin, HIGH); //Close the relay
delay(1000); //wait for 1 second
digitalWrite(relayPin, LOW); //disconnect the relay
delay(1000); //wait for 1 second
}
/*************************************************/

Hi Jason,

Please edit your post above to put [code] before the code, and [/code] after the code. Not only will it look prettier, but more people will actually read it.

EDIT: Paul’s function readRCData() is a function that he would need to write himself. He was demonstrating his own development procedure, he wasn’t writing your actual code.

Here is a sample sketch for the amp board.

include <Wire.h>
// 0x4B is the default i2c address
#define MAX9744_I2CADDR 0x4B
// We'll track the volume level in this variable.
int8_t thevol = 31;
void setup() {
Serial.begin(9600);
Serial.println("MAX9744 demo");
Wire.begin();
if (! setvolume(thevol)) {
Serial.println("Failed to set volume, MAX9744 not found!");
while (1);
}
}
// Setting the volume is very simple! Just write the 6-bit
// volume to the i2c bus. That's it!
boolean setvolume(int8_t v) {
// cant be higher than 63 or lower than 0
if (v > 63) v = 63;
if (v < 0) v = 0;
Serial.print("Setting volume to ");
Serial.println(v);
Wire.beginTransmission(MAX9744_I2CADDR);
Wire.write(v);
if (Wire.endTransmission() == 0)
return true;
else
return false;
}
// Read in + and - characters to set the volume.
void loop() {
if (! Serial.available()) return;
// read a character from serial console
char c = Serial.read();
// increase
if (c == '+') {
thevol++;
}
// decrease
else if (c == '-') {
thevol--;
}
// ignore anything else
elseif (thevol > 63) thevol = 63;
if (thevol < 0) thevol = 0;
setvolume(thevol);
}

Thank you ChrisTenone. Did that edit properly?

It did, but any time you enter code here, use the ‘code’ tags. See how you’ve got a guy with sunglasses, and italic text in the code above? Code tags fix that.

Thanks for the help.

I’ve worked on the sketch and decided to break the steps down to one at a time.

I decided to first deal with the 4 channels of PWM inputs.
I now have 4 sets of PWM amounts displayed on the serial monitor.
If I activate any of the four switches the PWM amount changes.

I then decided to work on making a 12V light turn on and off using a Arduino Uno compatible 5V relay module.

I was able to get the light to turn on for a second then turn off for a second and repeat.

I would like to use channel #3 (pin 6) to switch relay module on/off.

If ch3

if(time >= 1080 && time <= 1100)
{
   digitalWrite(relayPin, LOW);
}
else if(time >= 1880 && time <= 1900)
{
   digitalWrite(relayPin, HIGH);
}

My PC has no internet now so I can not cut and paste so I will write sketch again and post below.

int ch1;
int ch2;
int ch3;
int ch4;

const int relayPin =12;

void setup()  {

  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);

  pinMode(relayPin, OUTPUT);

  Serial.begin(9600);

}

void loop()  {

  ch1 = pulseIn(4, HIGH, 25000);
  ch2 = pulseIn(5, HIGH, 25000);
  ch3 = pulseIn(6, HIGH, 25000);
  ch4 = pulseIn(7, HIGH, 25000);

  Serial.print(Channel 1: ");
  Serial.println(ch1);

  Serial.print(Channel 2: ");
  Serial.println(ch2);

  Serial.print(Channel 3: ");
  Serial.println(ch3);

  Serial.print(Channel 4: ");
  Serial.println(ch4);

  delay(1000);

  //Can I add  "if" and "else" statements to 
  //complete task? For example--->
  //
  //if(time >= 1080 && time <= 1100)
  //{
  //digitalWrite(relayPin, LOW);
  //}
  //else if(time >= 1880 && time <= 1900)
  //{
  //digitalWrite(relayPin, HIGH);
  //}
}
  ch3 = pulseIn(6, HIGH, 25000);

Correct.

  Serial.print(Channel 3: ");
  Serial.println(ch3);

Good to KNOW what value we are dealing with.

  //Can I add  "if" and "else" statements to
  //complete task?

Yes, you can.

// For example--->
  //
  //if(time >= 1080 && time <= 1100)
  //{
  //digitalWrite(relayPin, LOW);
  //}
  //else if(time >= 1880 && time <= 1900)
  //{
  //digitalWrite(relayPin, HIGH);
  //}

Well, we KNOW that the interesting time is stored in a variable named ch3, and that there is no variable named time, so the answer is yes, you can, but, no, not that way.

Perhaps the right way will now be clear.

If not, it is generally far faster to ask the Arduino and compiler these kinds of questions.

PaulS:
there is no variable named time

Thanks everyone.
I was researching a way to name "time" in the scope but haven't had much luck. I'll keep searching.
I'm concentrating on the next step I was missing------->

"there is no variable named time"

Is there a good lesson in arduino.cc I can study that will point me in the right direction?

Is there a list of commands that would be useful?

In the mean time I'll keep researching "if" and "else" statement proceedures.

Thanks.

I found a couple tutorials for "if" and "else" statements but no luck so far on how to name time in the scope.
Will keep looking. Thanks.

Still looking.....
Any assistance would be awesome.
Thank you.

Paul said "there is no variable named time".

I think what he was saying is that you do not declare a variable named "time" in your program.

See at the top where you say: int ch3;

That is called a variable declaration. The variable name is ch3. The value of that variable, is as yet undefined because you haven't given it a value.

Then, later in your loop() function, you do some cool stuff with the pulseIn() function, and then assign the result as a value to the variable, ch3 and Serial.print() it. All very cool.

However, then you test an undeclared variable named time. The compiler chokes and gives you an error, because it has never heard of a variable named time. And no wonder! You never created it (by declaring it), nor gave it a value (by assigning a value to it.)

You can correct the issue by 1) declaring the variable time, just like you declared the variable ch3, at the beginning of your program, then 2) assigning the variable time the same value as the other variable ch3. The assignment operator is the equal sign, and it works by assigning the value on the right to the variable name on the left of the equal sign. So like this:

...
  time = ch3;
...

after you have assigned a value to ch3.

An alternative would be to forgo using a variable named time altogether, and just test the variable ch3, which already has the value you want to test.

It's not a problem with if ... else, you use that correctly. You need to create a variable named time or just don't use a variable by that name.

ps, sorry for the long windedness. I'm not being condescending, I want to be sure I'm not skipping a fundamental concept that you might have missed.