[edit]
PROBLEM SOLVED.
Thanks for the help - with a lot of help from you and geeks at the lab I have found the solution!
The program works as intended - for now.
-
char waitForKey() blocks everything. It unusable in this (and many other) scenarios. I've managed to apply char getKey() for the same purpose. It was kind of difficult since couldn't find any examples online.
-
My power source was corrupted - extra ground was needed, all-ok now.
-
Interrupt cable was connected to 10th pin - same as my SD card chipselect pin, now Interrupt is pin 19.
Program works as follows:
- Insert 1€ or more into the coin acceptor.
- Lcd shows you inserted amount, and informs you when 1€ is reached ("Skambink!")
- Dial a number (1441, 2552 or 3663).
- Hear a sound e.g. jonas.wav/petras.wav/antanas.wav
Code:
volatile float coinsValue = -0.10;
//Interrupt pin works somewhat difficult on DUE - sends a signal when DUE turns on, I offset value by one step
int coinsChange = 0;
//A Coin has been inserted flag
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <DAC.h>
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
#include <Key.h>
#include <Keypad.h>
#define I2C_ADDR 0x3F // Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
const byte ROWS = 4;
const byte COLS = 4;
int code1 = 1441; //The code I used, you can change it
int code2 = 2552; //The code I used, you can change it
int code3 = 3663; //The code I used, you can change it
int tot, i1, i2, i3, i4;
char c1, c2, c3, c4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
int keyCounter = 0;
Keypad myKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup() {
// debug output at 9600 baud
Serial.begin(9600);
//My LCD is 16x2
lcd.begin (16, 2);
SD.begin(10);
//for DUE - any digital pin as Interrupt pin
attachInterrupt(digitalPinToInterrupt(19), coinInserted, RISING);
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
lcd.print("Suma:");
}
void coinInserted()
//The function that is called every time it recieves a pulse
{
coinsValue = coinsValue + 0.10;
//As we set the Pulse to represent 5p or 5c we add this to the coinsValue
coinsChange = 1;
//Flag that there has been a coin inserted
}
char keypresses[4];
void loop() {
if (coinsChange == 1)
//Check if a coin has been Inserted
{
coinsChange = 0;
//unflag that a coin has been inserted
}
lcd.setCursor (0, 1); // go to start of 2nd line
//Print the Value of coins inserted
lcd.print(coinsValue);
Serial.println(coinsValue);
if (coinsValue >= 1)
{
lcd.setCursor (7, 1); // go to start of 2nd line
lcd.print("Skambink!");
Serial.println("Skambink!");
keypadInput();
}
}
void keypadInput() {
//getting the key when button is pressed instead of waitForKey
char customKey = myKeypad.getKey();
if (NO_KEY != customKey) {
//storing number into array
keypresses[keyCounter] = customKey;
//counting how many number we've got
keyCounter++;
Serial.print(customKey);
}
//if we have 4 numbers - proceed
if (keyCounter > 3)
{
keyCounter = 0;
//the keys pressed are stored into chars I convert them to int then i did some multiplication to get the code as an int of xxxx
i1 = (keypresses[0] - 48) * 1000;
i2 = (keypresses[1] - 48) * 100;
i3 = (keypresses[2] - 48) * 10;
i4 = keypresses[3] - 48;
tot = i1 + i2 + i3 + i4;
if (tot == code1) //if the code is correct you trigger to play .wav
{
playSound("jonas.wav");
}
else if (tot == code2)
{
playSound("petras.wav");
}
else if (tot == code3)
{
playSound("antanas.wav");
}
else if (tot == 0000)
{
playSound("test.wav");
}
else //if the code is wrong you get another thing
{
for (int j = 0; j < 256; j++) {
for (int i = 0; i < 256; i++)
analogWrite(DAC1, i);
}
playSound("blogas.wav");
}
}
}
// Playing assigned filename
void playSound(const char* cName) {
File myFile = SD.open(cName);
const int S = 1024; // Number of samples to read in block
short buffer[S];
// until the file is not finished
Serial.println("playing ");
Serial.println(cName);
Audio.begin(44100, 100);
while (myFile.available()) {
myFile.read(buffer, sizeof(buffer));
// Prepare samples
int volume = 1024;
Audio.prepare(buffer, S, volume);
Audio.write(buffer, S);
}
Audio.end();
myFile.close();
}
[end of edit]
Hi guys!
I am making this "phone", where users (children) use tokens/coins and keypad to make it speak (play .wav files) through the handset. For this project I am using i2c 16x2 LCD, 4x4 Keypad, SD shield + amplifier + speaker, Sparkfun 6 coin types acceptor, Arduino DUE.
The problem arise when I only allow to use keypad buttons when enough money is being put through the coin acceptor - code line 102.
When adding void keypadInput() in if or while statement I cannot send the names of .wav files to void playSound(const char* cName) . Everything else works as expected.
I know, I am a pretty lousy programmer. Here is my code, hopefully someone can spot my mistake(s):
Cheers! Have a nice Easter!
//code was removed, since it might misguide readers of the forum. For the right code look above or to the post #20.