Hackster is hosting Hackster Holidays, Ep. 5: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 5 on Friday!
vincent wong
Published © GPL3+

Twinkle Twinkle Little Star Musical Cup

A musical cup that plays "Twinkle Twinkle Little Star" upon pressing a button. Now, it plays "Happy Birthday to You" tune too.

IntermediateFull instructions provided773
Twinkle Twinkle Little Star Musical Cup

Things used in this project

Hardware components

Kinetis Freedom Board with FlexIO
NXP Kinetis Freedom Board with FlexIO
×1
Seeed Studio Grove - Starter Kit for Arduino
×1

Software apps and online services

NXP Kinetis Expert
NXP Kinetis Design Studio Integrated Development Environment (IDE)

Story

Read more

Schematics

Musical Cup

Code

main.c

C/C++
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 */

#include "board.h"
#include "fsl_port.h"

#include "fsl_debug_console.h"
#include "fsl_gpio.h"

#include "clock_config.h"
#include "pin_mux.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
//#define BOARD_LED_GPIO BOARD_LED_RED_GPIO
//#define BOARD_LED_GPIO_PIN BOARD_LED_RED_GPIO_PIN
#define BOARD_LED_GPIO GPIOD
#define BOARD_LED_GPIO_PIN 0U
//#define BOARD_LED_GPIO GPIOC
//#define BOARD_LED_GPIO_PIN 11U
#define GROVE_LED_GPIO GPIOC
#define GROVE_LED_GPIO_PIN 11U
#define GROVE_BUTTON_GPIO GPIOC
#define GROVE_BUTTON_GPIO_PIN 12U

#define CLK_SPEED 150000000   //Put your board's clock speed here in Hz, FRDM-K82F = 150000000

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief delay a while.
 */
void delay(void);

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/
void delay(void)
{
    volatile uint32_t i = 0;
    for (i = 0; i < 10000000; ++i)
    {
        __asm("NOP"); /* delay */
    }
}

void delay2(int t)
{
    volatile uint32_t i = 0;
    for (i = 0; i < t * 10000; ++i)
    {
        __asm("NOP"); /* delay */
    }

}

void delayMicroSeconds(int time)
{
    uint32_t delayNum = CLK_SPEED / 1000000 * time; //turn into 1 micros then multiply
    volatile uint32_t cnt = 0U;
    for(cnt = 0U; cnt < delayNum; ++cnt){
      __asm("NOP");
    }
}

int length = 30; // the number of notes
char notes[2][30] = {"ccggaagffeeddc ggffeedggffeed ", "ggagcb ggagdc gggecba  ffecdc "};
int beats[2][30] = {{ 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 }, { 3, 3, 2, 3, 1, 2, 4, 3, 3, 2, 3, 2, 1, 4, 3, 3, 4, 2, 1, 1, 2, 4, 4, 3, 3, 2, 1, 2, 1, 4 }};
int tempo = 30;

uint8_t which = 1;

void playTone(int tone, int duration) {
    for (long i = 0; i < duration * 1000L; i += tone * 2) {
//        GPIO_WritePinOutput(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, 20U);
        GPIO_SetPinsOutput(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
        delayMicroSeconds(tone);
        GPIO_ClearPinsOutput(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
        delayMicroSeconds(tone);
    }
    PRINTF("end tone\r\n");
}

void playNote(char note, int duration) {
    char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
        int tones[] = { 191, 170, 151, 143, 127, 113, 101, 95 };

    // play the tone corresponding to the note name
    for (int i = 0; i < 8; i++) {
        if (names[i] == note) {
            PRINTF("tone = %d, duration = %d\r\n", tones[i], duration);
            playTone(tones[i], duration);

        }
    }
}



/*!
 * @brief Main function
 */
int main(void)
{
    /* Define the init structure for the output LED pin*/
    gpio_pin_config_t led_config = {
        kGPIO_DigitalOutput, 0,
    };

    gpio_pin_config_t button_config = {
        kGPIO_DigitalInput, 0,
    };

    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* Print a note to terminal. */
    PRINTF("\r\n GPIO Driver example\r\n");
    PRINTF("\r\n The LED is taking turns to shine.\r\n");

    CLOCK_EnableClock(kCLOCK_PortD);

    PORT_SetPinMux(PORTD, 0U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTC, 12U, kPORT_MuxAsGpio);
    PORT_SetPinMux(PORTC, 11U, kPORT_MuxAsGpio);

    /* Init output LED GPIO. */
    GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);
    GPIO_PinInit(GROVE_BUTTON_GPIO, GROVE_BUTTON_GPIO_PIN, &button_config);
    GPIO_PinInit(GROVE_LED_GPIO, GROVE_LED_GPIO_PIN, &led_config);


    bool playing;
    int buttonState;
    int lastButtonState;
    int i;

//    int play = 0U;

    while (1)
    {
        buttonState = GPIO_ReadPinInput(GROVE_BUTTON_GPIO, GROVE_BUTTON_GPIO_PIN);

        if (buttonState == 0U && lastButtonState == 1U && playing == false) {
        	playing = true;
        	i = 0;
        	which = ++which % 2;
        	lastButtonState = buttonState;

        } else if (buttonState == 0U && lastButtonState == 1U && playing == true) {
        	playing = false;
        	lastButtonState = buttonState;
        } else {
        	lastButtonState = buttonState;
        }



        if (playing) {
				PRINTF("note = %c\r\n", notes[i]);

				if (notes[which][i] == ' ')
				{
					delay2(beats[which][i] * tempo); // rest
					PRINTF("rest\r\n");
				}
				else
				{
					if (notes[which][i] == 'c' || notes[which][i] == 'e' || notes[which][i] == 'g' || notes[which][i] == 'b') {
						GPIO_WritePinOutput(GROVE_LED_GPIO, GROVE_LED_GPIO_PIN, 1U);
					} else {
						GPIO_WritePinOutput(GROVE_LED_GPIO, GROVE_LED_GPIO_PIN, 0U);
					}

					PRINTF("note = %c, duration = %d\r\n", notes[which][i], beats[which][i] * tempo);
					playNote(notes[which][i], beats[which][i] * tempo);
				}

				// pause between notes
				delay2(tempo / 2);

				if (++i >= length) {
					playing = false;
				}

    	}
    }

    PRINTF("end\r\n");

    while (1) {}
}

Credits

vincent wong

vincent wong

81 projects • 205 followers

Comments