Show Posts
Pages: [1] 2 3
1  Using Arduino / Programming Questions / Re: I can't find what is wrong in my code (newbie) on: June 03, 2014, 02:01:43 am
I'm lost with all these terms (English is not my mother tongue)
If you need more help, try to post your problem on the French section. Regarding the names of your declarations in your code, I assume "tu est Francophone" smiley
2  Using Arduino / Programming Questions / Re: Array from function only partial on: June 01, 2014, 03:34:53 pm
A big part of the problem is that the OP never explained the whole thing or posted all of his code. So we have only come to know about fastLED after a lot of wasted speculation on other options.
That's true, you're right and I am sorry. Initially my problem was that mistake of the pointer. Then it became a bit OT because I reported the next problem I encountered. Finally the code is working as I wish to have it and since there's nothing to hide about my project, I can post you the entire sketch as it works now:
Code:
/*
Christmas 2014 LED dot matrix on balcony.
This sketch controls 50 RGB LEDs controlled by WS2801
and displays digit 1-31.

May 2014 - rediculum
*/

// Libs
#include "FastLED.h"
#include <Wire.h>
#include <RealTimeClockDS1307.h>
#include "BitBool.h"
#include "XMas14_RGB.h"

// Pin outs
/*
RTC SDA = A4
RTC SCL = A5   */
#define DATA_PIN 3
#define CLOCK_PIN 13

// Define the array of leds and var declarations
#define NUM_LEDS 50
byte today, yesterday, arrSize, arrElement;
CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(115200);
  Serial.println(F("XMas14 RGB Lights"));
 
  FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
  //FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
}

void loop() {
  // Read day from RTC
  RTC.readClock();
  today = RTC.getDay();
 
  // Count amount of bits (1) in matrix for that row (today) and define the array size
  arrSize = 0;
  for (byte i = 0; i < 50; i++) {
    if (matrix[today][i] == 1) {
      arrSize++;
    }   
  }
  byte numArray[arrSize];

  Serial.print(("Displaying number: "));
  Serial.print(today);   
  Serial.print(F(" (array size "));
  Serial.print(arrSize);
  Serial.println(F(")"));

  // Fill the LED number into the defined array.
  // Array element 0 is LED 1, element 49 is LED 50, and so on!
  arrElement = 0;
  for (byte i = 0; i < 50; i++) {
    if (matrix[today][i] == 1) {
      numArray[arrElement] = i + 1;
      Serial.print(i + 1); Serial.print(F(" "));
      arrElement++;
    }
  }
  Serial.println(F(""));Serial.println(F("---------------------")); // Separator
 
  if (yesterday != today) {
    // Clear all LEDs and draw new number when day changes or Arduino starts (yesterday == NULL)
    Serial.println(F(" New day, clearning LEDs"));
    FastLED.clear();
   
   
    // Update current day
    yesterday = today;
    delay(1000);   
   
    Serial.print("Fade in LED ... ");
    // Fade in new number with random colours
    for (byte i = 0; i < arrSize; i++) {
      fadeInRandColour(numArray[i]);
    }
    Serial.println(" done");
  }
  delay(1000);
   
  // Randomly change color of a single LED 1000 times fastly
  Serial.print("Random Color change ...");
  for (int i = 0; i < 1000; i++) {
    randColour(numArray[random(0,arrSize)]);
    FastLED.show();
    delay(10);
  }
  Serial.println(" done");

  delay(3000);
 
  // Rainbow with all LEDs at once
  Serial.print("Rainbow Color ...");
  for (byte color = 0; color < 255; color++) {
    for (byte led = 0; led < arrSize; led++) {
      setColour(numArray[led],color);
      FastLED.show();
    }
    delay(10);
  }
  Serial.println(" done");

  delay(3000);
  Serial.println(F(""));Serial.println(F("End of loop"));
}



//================================================================================================



// Fades one LED in by a given colour 0-255)
void fadeInColour(byte led, byte hue){
  for (byte i = 0; i < 255; i++) {
    leds[led].setHSV(hue,255,i);
    FastLED.show();
    delay(1);
  }
}

// Fades one LED in by a random colour
void fadeInRandColour(byte led) {
  randColour(led);
 
  // Fade in that LED
  for (byte i = 0; i < 255; i++) {
    leds[led].fadeLightBy(i);
    FastLED.show();
    delay(1);
  }
}

// Sets one LED to a random colour.
// Does not invoke FastLED.show()!
void randColour(byte led) {
  // Random colour by RGB values
  //leds[led].setRGB(random(0,255),random(0,255),random(0,255));
 
  // Random colour by hex values
  leds[led].setHSV(random(0,255),255,255);
}

// Sets one LED to a specified colour.
// Does not invoke FastLED.show()!
void setColour(byte led, byte hue) {
  leds[led].setHSV(hue,255,255);
}

XMas14_RGB.h
Code:
/*
The matrix for the dots to display number 0 to 31

This header file is needed by XMAS14_RGB.ino and requires
BitBool.h by pYro_65 http://forum.arduino.cc/index.php?topic=128407.0

May 2014 - rediculum
*/
#ifndef XMas14_RGB_h
#define XMas14_RGB_h
  

BitBool< 50, true > matrix[32] = {
/*                            1           2           3           4             5
LED Matrix WS2801  12345678  90123456  78901234  56789012  34567890  12345678  90  */
                 {B00001101,B00100000,B01001100,B10000001,B00110010,B00000001,B10000000}, // 0
                 {B00000100,B11000000,B00010010,B00000000,B01001000,B00000000,B10000000}, // 1
                 {B00011101,B00000000,B00001011,B00000001,B00000010,B00000011,B11000000}, // 2
{B00011101,B00000000,B00001011,B00000000,B00110000,B00000011,B10000000}, // 3
                 {B00010011,B00100000,B01001111,B10000000,B00110000,B00000000,B01000000}, // 4
                 {B00011110,B00100000,B01000011,B10000000,B00110000,B00000011,B10000000}, // 5
                 {B00001100,B00100000,B01000011,B10000001,B00110010,B00000001,B10000000}, // 6
                 {B00011111,B00000000,B00001010,B00000000,B10000100,B00000001,B00000000}, // 7
                 {B00001101,B00100000,B01001011,B00000001,B00110010,B00000001,B10000000}, // 8
                 {B00001101,B00100000,B01001111,B00000000,B00110000,B00000011,B10000000}, // 9

         {B00101101,B00101101,B01001100,B11000101,B00110010,B10001001,B10000000}, // 10
                 {B00100100,B11001101,B00010010,B01000100,B01001000,B10001000,B10000000}, // 11
                 {B00111101,B00001101,B00001011,B01000101,B00000010,B10001011,B11000000}, // 12
{B00111101,B00001101,B00001011,B01000100,B00110000,B10001011,B10000000}, // 13
                 {B00110011,B00101101,B01001111,B11000100,B00110000,B10001000,B01000000}, // 14
                 {B00111110,B00101101,B01000011,B11000100,B00110000,B10001011,B10000000}, // 15
                 {B00101100,B00101101,B01000011,B11000101,B00110010,B10001001,B10000000}, // 16
                 {B00111111,B00001101,B00001010,B01000100,B10000100,B10001001,B00000000}, // 17
                 {B00101101,B00101101,B01001011,B01000101,B00110010,B10001001,B10000000}, // 18
                 {B00101101,B00101101,B01001111,B01000100,B00110000,B10001011,B10000000}, // 19

{B11101101,B00110000,B11001100,B11110001,B00110010,B01111101,B10000000}, // 20
                 {B11100100,B11010000,B10010010,B01110000,B01001000,B01111100,B10000000}, // 21
                 {B11111101,B00010000,B10001011,B01110001,B00000010,B01111111,B11000000}, // 22
{B11111101,B00010000,B10001011,B01110000,B00110000,B01111111,B10000000}, // 23
                 {B11110011,B00110000,B11001111,B11110000,B00110000,B01111100,B01000000}, // 24
                 {B11111110,B00110000,B11000011,B11110000,B00110000,B01111111,B10000000}, // 25
                 {B11101100,B00110000,B11000011,B11110001,B00110010,B01111101,B10000000}, // 26
                 {B11111111,B00010000,B10001010,B01110000,B10000100,B01111101,B00000000}, // 27
                 {B11101101,B00110000,B11001011,B01110001,B00110010,B01111101,B10000000}, // 28
                 {B11101101,B00110000,B11001111,B01110000,B00110000,B01111111,B10000000}, // 29

{B11101101,B00110000,B11001100,B11100011,B00110011,B00111001,B10000000}, // 30
                 {B11100100,B11010000,B10010010,B01100010,B01001001,B00111000,B10000000}, // 31                
};

#endif //XMas14_RGB.h

It's not finished yet and I will append some more colour scenes.

Maybe there's some optimization or another approach on how to address the LED matrix, but I am not expecting that you spend your time for me. As you like smiley
3  Using Arduino / Programming Questions / Re: Array from function only partial on: May 30, 2014, 05:43:21 am
 String of 50 LEDs controlled by WS2801 IC. You address the LED by the number of it's position in the string. The FastLED library is handling that for you. From those 50 LEDs I want LED 25 to be lit in red, I simply invoke
Code:
leds[25] = CRGB::Red; FastLED.show();

As soon I got my LEDs mounted I post a video and the final code in the related section of the Arduino forum.
4  Using Arduino / Programming Questions / Re: Array from function only partial on: May 30, 2014, 03:10:42 am
That's it, thanks! Lesson learned.
I extended now my code to fill in the new array with the LED number and until now everything looks fine and my project goes forward! Many thanks for your support pYro_65 and all others here for your replies.
@Robin2, at the end I need an integer from 1  to 50 to contol one LED by the FastLED library, not a bit.

Code:
#include "BitBool.h"
BitBool< 50, true > matrix[ 31 ] = {  //The true makes the LSB bit 8 rather than bit 0
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 }, //Last 6 bits aren't used.
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B01100100, B00010001, B10010000, B10101000, B00001100, B00100001, B11000000 },
  { B01100100, B00010001, B10010000, B10101000, B00001100, B00100001, B11000000 },
  //...
};

byte arrSize;

void setup() {
  Serial.begin(9600);
  for ( byte i = 0; i < 50; i++ ) {
    if ( matrix[5][i] == 1 ) {
      arrSize++;
    }
  }
  Serial.print("Arrsize: ") ;
  Serial.println(arrSize);
 
  byte numArray[arrSize];
  byte arrElement = 0;
 
  for (byte i = 0; i < 50; i++ ) {
    if ( matrix[5][i] == 1 ) {
      numArray[arrElement] = i + 1;
      arrElement++;
    }
  }
 
  for (byte i = 0; i < arrSize; i++ ) {
      Serial.println(numArray[i]);
  }

}

void loop() {}
5  Using Arduino / Programming Questions / Re: Array from function only partial on: May 30, 2014, 02:32:59 am
pYro_65, your BitBool looks not bad. I've tried to apply it to my needs but now I get stuck how to convert that single row of bits into an array of numbers according to the LED.
I tried to determine the size of the array according the amount of 1 the row has. For example:
Code:
#include "BitBool.h"

BitBool< 50, true > matrix[ 31 ] = {  //The true makes the LSB bit 8 rather than bit 0
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 }, //Last 6 bits aren't used.
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  { B11001100, B00000001, B11110000, B10101010, B11001100, B00000001, B11000000 },
  //...
};

byte arrSize;

void setup() {
  Serial.begin(9600);
  for ( byte i = 0; i < 50; i++ ) {
  if ( matrix[5][i] == 1 ) {
    Serial.print("LED: " + i);
    arrSize++;
    }
  }
  Serial.println(" - Arrsize: " + arrSize);
}

void loop() {}
But that gives me again some weird output on the monitor
Code:
LED: ED:  e: :  ’¢¢õð`ÅÅ¢
6  Using Arduino / Programming Questions / Re: Array from function only partial on: May 28, 2014, 11:57:05 am
yeah you're right. But even if I change it to byte I got the same problem of SRAM  smiley-cry
Any other solutions?
7  Using Arduino / Programming Questions / Re: Array from function only partial on: May 28, 2014, 11:33:01 am
Ok guys, I simplified the entire code now to show what's the real goal of my sketch. I have 50 WS2801 LEDs which I want to align to a 4x7 matrix and display number 0 to 31 (later maybe more) with the help of the FastLED library. The matrix looks like this


As you can see, to display a "1", I need to illuminate LED 6,9,10,20,23,34,37 and 49. That's why I create an array called one
Code:
byte one[8] = {6,9,10,20,23,34,37,49};
So I do this for all digits from 0 to 31.
Next I read the current day from the RTC which gives me that as an integer 1..31. So what I finally want is to pick the right array depending on the current day as number. Something like this:
Code:
byte one[8] = {6,9,10,20,23,34,37,49};
byte two[x] = {n,n,n,n,n,n,n,n,n,n}; // next number, etc

int today = 1; // read from RTC
  
 switch (today)
    case 1: //define a new array called numArray and point to "one[]" with the same size
    case 2: // define the array numArray here and poin to "two[]"
  }
 
  for (int i = 0; i < sizeof(numArray); i++) {
    int led = numArray[i];
   // illuminate that led number
  }
}
I get stuck here and I am pretty sure there must be a way to program this. I appreciate any help. If this approach is not possible, do you know any methods on how to handle my LED matrix? I also tried by creating a 2d array and parsing every single LED  to be on (1) or off (0)
Code:
/*                                       1                   2                   3                   4                   5
LED Matrix of WS2801   1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0  */
int matrix[31][50] = {{0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0},
                      {0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0},
                      ....
                      ....
but that does not work beause the array is too big for the SRAM.
8  Using Arduino / Programming Questions / Re: Array from function only partial on: May 27, 2014, 09:54:59 am
If you want to do what you're trying to do, then the caller needs to allocate the array and pass a pointer to it to the function. 
Thanks for your reply. Is this applicable to my code? I am getting desperate with this programming language  smiley-sad
9  Using Arduino / Programming Questions / Array from function only partial on: May 27, 2014, 07:30:38 am
Hello guys (n'girls)

I have a strange behavior when dealing with Arrays and return them from a function. Simple words: Why does my code only print the first 2 elements for the array?

Code:
int today;

void setup() {
  Serial.begin(9600);
  today = 1;
 
  byte* numArray = getNumber(today);
  Serial.print("Displaying number ");
  Serial.print(today);
  Serial.print(" (");
  Serial.print(sizeof(numArray));
  Serial.print(") :");

  for (int i = 0; i < sizeof(numArray); i++) {
    int led = numArray[i];
    Serial.print(led);
    Serial.print(" ");
  }
}

void loop() {
true;
}

byte *getNumber(int x) { 
  switch (x) {
    case 1: static byte one[8] = {6,9,10,20,23,34,37,49}; return(one); break;
  }
}

Monitor output:
Code:
Displaying number 1 (2) :6 9
10  International / Deutsch / Re: Mein neuestes Projekt - Temperaturlogger - Temperatur in Datenbank speichern on: January 21, 2014, 06:40:36 am
ntop nutzt die RoundRobinDatabase von Tobi Oetiker, der Autor von MRTG smiley
Also eher umgekehrt, ntop sieht aus wie MRTG
11  International / Deutsch / Re: Mein neuestes Projekt - Temperaturlogger - Temperatur in Datenbank speichern on: January 15, 2014, 10:24:53 am
Cooles Projekt.

Ich habe was ähnliches gebaut um die Temp. unseres Warmwasser-Boilers zu messen. Dazu habe ich ein ENC28J60 an ein Nano gehängt und einen MiniWebserver geschrieben der auf HTTP requests mit den Werten der analogen Temperaturfühler (LM35)  antwortet. Die Werte hab ich mittels Linux Befehl "curl" abgefragt und an MRTG übergeben, der mir die Graphs erstellt hat.
Hier der Code:

Code:
/*
BoilMonDuino 1.0
================
Designed and programmed by ReDiculum (Roland Hansmann)
 
This is an active heat monitor for our warm water boiler.
There is an LM35 analog temp sensor attached on a outbound
tube attached to the boiler.
Thresholds and alerting is handled by external tools querying
the temperature over periodical HTTP requests.

Example MRTG UNIX subcommand:
`curl IPAddress`

The basic code is provided from the Arduino Forum sample
for a basic web server using EtherShield and EHTER_28J60
libraries from
http://trollmaker.com/article11/arduino-1-0-with-enc28j60-ethernet-shield-v1-1

CS = D10 (brown)
SI = D11 (orange)
SO = D12 (purple)
SCK = D13 (grey)
RST = RESET (white)
VCC = 3.3V (red)
GND = GND (black)
 
Use at your own risk!
*/

// Libraries
#include "etherShield.h"
#include "ETHER_28J60.h"

// ethernet interface mac address, must be unique on the LAN
static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};
static uint8_t ip[4] = {10,0,72,72}; // IP address for the webserver
static uint16_t port = 80; // Use port 80 - the standard for HTTP

// Declarations
#define TEMP_SENSOR_WARMWASSER_PIN 0      // Analog Input 0
#define TEMP_SENSOR_ERWAERMER_PIN 1 // Analog Input 1
unsigned int tempWarmwasser;
unsigned int tempErwaermer;


ETHER_28J60 e;  // Create object

void setup () {
  Serial.begin(57600);
  
  e.setup(mac, ip, port);
}


void loop () {
  
  // Softreset every 30min  
  if (millis() >= 1800000) {
     asm volatile ("  jmp 0"); // Soft Reset
  }
  
  char* params;
  if (params = e.serviceRequest())
  {
    tempWarmwasser = (4.2 * analogRead(TEMP_SENSOR_WARMWASSER_PIN) * 100.0) / 1024;
    tempErwaermer = (4.2 * analogRead(TEMP_SENSOR_ERWAERMER_PIN) * 100.0) / 1024;
    e.print(tempWarmwasser);
    e.print("\r\n");
    e.print(tempErwaermer);
    e.print("\r\n");
    e.respond();
  }
}
12  Community / Exhibition / Gallery / Playing with Nokia LCD 3310 on: January 10, 2014, 11:23:21 am
I spent some hours in playing with the Nokia LCD and some input devices, so I wanted to share that funny thing.
What you need:

- Breadboard
- Arduino (I used a nano)
- Nokia 3310 LCD
- DS1307 RTC
- 10kOhm poti
- Photoresistor and a 620ohm Resi.
- Some jumper wires

Attach all components like described in the links in the code or Arduino Playground and you should get this funny stuff working well.

Code:
/* Playing with Nokia LCD 3310 by ReDiculum Jan. 2014

Use at your own risk
*/

//https://code.google.com/p/pcd8544/
#include <PCD8544.h>

//https://github.com/davidhbrown/RealTimeClockDS1307
#include <Wire.h>
#include <RealTimeClockDS1307.h>

static PCD8544 lcd;

void setup() {
   lcd.begin(84, 48);
}

void loop() {
  // Potentiometer on A3
  lcd.setCursor(0,0); lcd.clearLine();
  int potValue = map(analogRead(3),0,1023,0,100);
  lcd.print("Poti: ");
  lcd.print(potValue);
  lcd.print("% ");
  drawBar(0, map(potValue,0,100,403,420));
  
  // Phototransistor on A6
  lcd.setCursor(0,2); lcd.clearLine();
  int phoValue = map(analogRead(6),0,1023,100,0);
  lcd.print("Phot: ");
  lcd.print(phoValue);
  lcd.print("% ");
  drawBar(2, map(phoValue,0,100,403,420));

  // RealTimeClock on A4+5
  lcd.setCursor(0,4); lcd.clearLine();
  lcd.print("Time: ");
  RTC.readClock();
  lcd.print(RTC.getHours());  lcd.print(":");
  lcd.print(RTC.getMinutes());  lcd.print(":");
  lcd.print(RTC.getSeconds());
}

void drawBar(int line, int val) {
  for (int i = 403; i <= val; i++) {
    lcd.setCursor(i,line);
    lcd.drawColumn(0,8);
  }    
}



Poti playing


Photoresi playing
13  Community / Exhibition / Gallery / Re: Fairy Tale Phone on: January 06, 2014, 04:41:35 am
Finally I also used the SimpleSDAudio library and finished the project. Here's the final code and some pictures
Code:
/*
=============================================================================================
Fairy Tale Phone 1.0
by ReDiculum (Oct. - Dez. 2013)
-------------------------------
X-Mas 2013 Arduino project.
Using an old Zellweger Modell 70 (anno 1982) telephone with dial wheel.
The wheel can be spinned to count impulses and then playing one of ten different
audio fairies stored as 8bit full-rate (62500) mono PCM files named from 1.PCM to 10.PCM

SD Card > Arduino pinout:

CS (1)   -> Pin 10 (Chip select)
MOSI (2) -> Pin 11
MISO (7) -> Pin 12
SCK  (5) -> Pin 13

Ear phone  -> Pin 9 (protect with Diode against Pin 3) and GND
Dial wheel -> Pin 2 and GND
 
=============================================================================================

SimpleSDAudio library for audio playback from SD card
http://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio
*/
#include <SimpleSDAudio.h>

#define IMPULSE_PIN 2 // Digital Pin 2. Read impulses
#define PHONE_PIN 3 // Digital Pin 3 (PWM) for phone tone output (protect with Diode against Pin 9)
#define SD_CHIPSELECT_PIN 10  // Digital Pin 10. SD Card chip select.
#define LED_PIN 13 // Digital Pin 13
#define TIME_WAIT 2000 // Waiting 2sec during dial wheel turns. Sufficient to catch 10 impulses
int countImpulse = 0; // The magic number to "dial" the music track number.

/* Sum of running millis and TIME_WAIT.
Must be long integer if kids are not dialing quickly :)
*/
unsigned long timeWaitEnd = 0;

void setup() {
  Serial.begin(57600); // Set console to 57600 baud
  Serial.println("=== FairyTalePhone based on SSDA ===");  

  pinMode(LED_PIN, OUTPUT); // onboard LED

  /* Turn on internal pullup resistor, because we pull the pin to ground.
  When the wheel gives impulse, the contact is opened (no current). That's
  when we have a digitalRead = 1.
  */
  digitalWrite(IMPULSE_PIN, HIGH);

  Serial.println("Ready to dial ...");

  // Play tone and wait here until the dial wheel has sent his first impulse
  tone(PHONE_PIN,420);
  while (digitalRead(IMPULSE_PIN) == 0) {
    delay(1);
  }
  noTone(PHONE_PIN); // Pssht! Here we go!

  Serial.print("Counting impulses ");
  timeWaitEnd = millis() + TIME_WAIT; // Summarize already passed millis since Arduino runs and TIME_WAIT.

  // Count all the dialed impulses until timeWaitEnd has reached
  while (millis() < timeWaitEnd ) {      
    if (digitalRead(IMPULSE_PIN) == 1) {
      /* Increment the amount of impulses if the contacts are opened.
      The wheel pulses with an interval of approx 70ms
      */
      countImpulse++;
      Serial.print(".");
      digitalWrite(LED_PIN, HIGH); // Blink LED ...
      tone(PHONE_PIN,1000); // ... and short tone (70ms) of 1khz to fill the gap
      delay(70);
      digitalWrite(LED_PIN,LOW);
      noTone(PHONE_PIN);
    }
  }

  Serial.println(" "); // New line

  /* If the dial wheel has been turned more than once by nervous kids
  and the amount of counted impulses exceeds 10, we just restart Arduino
  */
  if (countImpulse > 10) {
    Serial.print("Count exceeded 10 ("); Serial.print(countImpulse); Serial.println("), restarting");
    hangOff();
    asm volatile ("  jmp 0"); // Soft Reset
  } else {
    Serial.print("Preparing fairy tale number "); Serial.println(countImpulse);
    

    // Set Chip Select Pin
    SdPlay.setSDCSPin(SD_CHIPSELECT_PIN);
    // Initialize SD Card with library SimpleSDAudio
    if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER)) {
      tone(PHONE_PIN,100); delay(250); noTone(PHONE_PIN); delay(400);
      tone(PHONE_PIN,80); delay(600); noTone(PHONE_PIN);
      Serial.println("Error initializing SD Card");
      while(1);
    }

    /* define a char array with an index size of 6 and convert
    integer "countImpulse" to char "track" using utoa() function
    http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html
    */
    char track[6];
    utoa(countImpulse,track,10);
    // Append the suffix .PCM to the char array
    strcat(track, ".PCM");
    
    // Set the audio file if it exists and play it
    if (SdPlay.setFile(track)) {
      Serial.print("Playing..."); Serial.println(track);
      SdPlay.play();
      while(!SdPlay.isStopped()) {
        ;
      }
      SdPlay.deInit();
      hangOff();
      // That's it, we jump into loop() function
    } else {
      SdPlay.deInit();
      Serial.print("File "); Serial.print(track); Serial.println(" not found");
      tone(PHONE_PIN,80); delay(250); noTone(PHONE_PIN); delay(400);
      tone(PHONE_PIN,120); delay(600); noTone(PHONE_PIN);
    }
  }
}

void loop(void) {
    ; // Nothing to do here
    //asm volatile ("  jmp 0"); // or Soft Reset?
}

void hangOff(){
  // Hang off tone 5x
  delay(1000);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
}

Fritzing Layout






14  Community / Exhibition / Gallery / Re: Fairy Tale Phone on: December 13, 2013, 06:27:06 am
You say "fairy tales"; unless they are very short, are you including a function to remember the present position (and rewind a couple of seconds) when it goes on-hook?
I will upload max 5min swiss fairy tales which I ripped form old compact cassettes (tapes).
By hooking on, the power will interrupt the Pro Mini. Hooking off will power on the board. No store of current playing position.
15  Community / Exhibition / Gallery / Fairy Tale Phone on: December 13, 2013, 02:16:22 am
Hello Arduino Community

Here's my recent project as a X-Mas gift for my daughters. Using an old telephone with dial wheel and build in a Pro Mini with SD Card to play fairy tales over the ear phone.
I am not yet finished since I am waiting for the SD break out. Until now I soldered some pins on a MicroSD Adapter and a L78L33 regulator to get the stuff working properly

Here's some impressions:




Fist try to catch the impulse signal from the dial wheel and count them. Also playing with tone().


Prototype with all components


And here's the code with the TMRpcm library
Code:
/*
=============================================================================================
Fairy Tale Phone 1.0
by ReDiculum (Oct. - Dez. 2013)
-------------------------------
X-Mas 2013 Arduino project.
Using an old Zellweger Modell 70 (anno 1982) telephone with dial wheel.
The wheel can be spinned to count impulses and then playing one of ten different
audio fairies stored as 8bit 16.000khz mono WAV files named from 1.wav to 10.wav

SD Card > Arduino pinout:

CS (1)   -> Pin 4 (Chip select)
MOSI (2) -> Pin 11
MISO (7) -> Pin 12
SCK  (5) -> Pin 13

Ear phone  -> Pin 9 (protect with Diode against Pin 3) and GND
Dial wheel -> Pin 2 and GND
 
=============================================================================================

TMRh20's pcm library for Arduino
https://github.com/TMRh20/TMRpcm
*/
#include <SD.h>
#include <TMRpcm.h>
#include <SPI.h>

#define IMPULSE_PIN 2 // Digital Pin 2
#define PHONE_PIN 3 // Digital Pin 3 (PWM)
#define SD_CHIPSELECT_PIN 4  // SD
#define LED_PIN 13 // Digital Pin 13
#define TIME_WAIT 2000 // Waiting 2sec during dial wheel turns. Sufficient to catch 10 impulses
int countImpulse = 0;
unsigned long timeWait = 0;

TMRpcm music;  // Create object "music" from class "TMRpcm"

/* Sum of running millis and TIME_WAIT.
Must be long integer if kids are not dialing quickly :)
*/
unsigned long timeWaitEnd = 0;

void setup() {
  Serial.begin(57600); // Set console to 57600 baud
  Serial.println("=== FairyTalePhone based on TMRpcm ===");  

  pinMode(LED_PIN, OUTPUT); // onboard LED
  
  music.speakerPin = 9; // Set Pin for SD card audio output

  /* Turn on internal pullup resistor, because we pull the pin to ground.
  When the wheel gives impulse, the contact is opened (no current). That's
  when we have a digitalRead = 1.
  */
  digitalWrite(IMPULSE_PIN, HIGH);

  Serial.println("Ready to dial ...");

  // Play tone and wait here until the dial wheel has sent his first impulse
  tone(PHONE_PIN,420);
  while (digitalRead(IMPULSE_PIN) == 0) {
    delay(1);
  }
  noTone(PHONE_PIN); // Pssht! Here we go!

  Serial.print("Counting impulses ");
  timeWaitEnd = millis() + TIME_WAIT; // Summarize already passed millis since Arduino runs and TIME_WAIT.

  // Count all the dialed impulses until timeWaitEnd has reached
  while (millis() < timeWaitEnd ) {      
    if (digitalRead(IMPULSE_PIN) == 1) {
      /* Increment the amount of impulses if the contacts are opened.
      The wheel pulses with an interval of approx 70ms
      */
      countImpulse++;
      Serial.print(".");
      digitalWrite(LED_PIN, HIGH); // Blink LED ...
      tone(PHONE_PIN,1000); // ... and short tone (70ms) of 1khz to fill the gap
      delay(70);
      digitalWrite(LED_PIN,LOW);
      noTone(PHONE_PIN);
    }
  }

  Serial.println(" "); // New line

  /* If the dial wheel has been turned more than once by nervous kids
  and the amount of counted impulses exceeds 10, we just restart Arduino
  */
  if (countImpulse > 10) {
    Serial.print("Count exceeded 10 ("); Serial.print(countImpulse); Serial.println("), restarting");
    hangOff();
    asm volatile ("  jmp 0"); // Soft Reset
  } else {    
    Serial.print("Preparing fairy tale number "); Serial.println(countImpulse);
    
    // Initialize SD Card with library SimpleSDAudio
    if (!SD.begin(SD_CHIPSELECT_PIN)) {
      tone(PHONE_PIN,100); delay(250); noTone(PHONE_PIN); delay(400);
      tone(PHONE_PIN,80); delay(600); noTone(PHONE_PIN);
      Serial.println("Error initializing SD Card");
      while(1);
    }

    /* define a char array with an index size of 6 and convert
    integer "countImpulse" to char "track" using utoa() function
    http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html
    */
    char track[6];
    utoa(countImpulse,track,10);
    // Append the suffix .wav to the char array
    strcat(track, ".wav");
    
    // Play the audio file
    music.play(track);
    Serial.print("Playing..."); Serial.println(track);
    while (music.isPlaying() == 1) {
      true; // play WAV file number and wait until it's finished
    }
    hangOff(); // That's it, we jump into loop() function    
  }
}

void loop() {
  ;// Nothing to do
  //asm volatile ("  jmp 0"); // Soft Reset
}

void hangOff(){
  // Hang off tone 5x
  delay(1000);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
  tone(PHONE_PIN,450); delay(250);
  noTone(PHONE_PIN); delay(250);
}
Pages: [1] 2 3