Audio Error In My Arduino Lightsaber Project

Hello there;

I am trying to make a lightsaber project with Arduino Nano ATmega328P processor.

I made all the connections in the schematic (except the led)

Then I loaded the necessary libraries and the code I gave in the attachment.

The sound should have been like the classic lightsaber sound, but ([August 5, 2022 - YouTube) sounds like this link.

Also, the MPU6050 light is on, but when I shake it, the sound does not change.

The control button in the diagram below does not work either, but the mushroom led is on.

Where do you think the problem might be?

Thank you and may the Force be with you!

Arduino code:


// ---------------------------- Settings -------------------------------
#define NUM_LEDS 30         // 
#define BTN_TIMEOUT 800     // 
#define BRIGHTNESS 255      //

#define SWING_TIMEOUT 500   
#define SWING_L_THR 150     
#define SWING_THR 300       
#define STRIKE_THR 150      /
#define STRIKE_S_THR 320    
#define FLASH_DELAY 80      // 

#define PULSE_ALLOW 1       // (1 - on, 0 - off)
#define PULSE_AMPL 20       // 
#define PULSE_DELAY 30      // 

#define R1 100000           // 
#define R2 51000            // 
#define BATTERY_SAFE 1      // state of charge (1 - on, 0 - off)

#define DEBUG 1             // port ekranın hata bilgileri görme (1 - on, 0 - off)
// ---------------------------- AYARLAR -------------------------------

#define LED_PIN 6
#define BTN 3
#define IMU_GND A1  /
#define SD_GND A0   //
#define VOLT_PIN A6
#define BTN_LED 4

// -------------------------- LIBRARY---------------------------
#include <avr/pgmspace.h>   // PROGMEM 
#include <SD.h>
#include <TMRpcm.h>         // SD library sound
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include <toneAC.h>         // Hum voice library
#include "FastLED.h"        //addressable led
#include <EEPROM.h>

CRGB leds[NUM_LEDS];
#define SD_ChipSelectPin 8
TMRpcm tmrpcm;
MPU6050 accelgyro;
// -------------------------- KULLANILAN KÜTÜPHANELER ---------------------------


// ------------------------------ DEĞİŞKENLER ---------------------------------
int16_t ax, ay, az;
int16_t gx, gy, gz;
unsigned long ACC, GYR, COMPL;
int gyroX, gyroY, gyroZ, accelX, accelY, accelZ, freq, freq_f = 20;
float k = 0.2;
unsigned long humTimer = -9000, mpuTimer, nowTimer;
int stopTimer;
boolean bzzz_flag, ls_chg_state, ls_state;
boolean btnState, btn_flag, hold_flag;
byte btn_counter;
unsigned long btn_timer, PULSE_timer, swing_timer, swing_timeout, battery_timer, bzzTimer;
byte nowNumber;
byte LEDcolor;  // 0 - kırmızı, 1 - yeşil, 2 - mavi, 3 - mor, 4 - sarı, 5 - buz mavisi
byte nowColor, red, green, blue, redOffset, greenOffset, blueOffset;
boolean eeprom_flag, swing_flag, swing_allow, strike_flag, HUMmode;
float voltage;
int PULSEOffset;
// ------------------------------ DEĞİŞKENLER ---------------------------------

// --------------------------------- SESLER ----------------------------------
const char strike1[] PROGMEM = "SK1.wav";
const char strike2[] PROGMEM = "SK2.wav";
const char strike3[] PROGMEM = "SK3.wav";
const char strike4[] PROGMEM = "SK4.wav";
const char strike5[] PROGMEM = "SK5.wav";
const char strike6[] PROGMEM = "SK6.wav";
const char strike7[] PROGMEM = "SK7.wav";
const char strike8[] PROGMEM = "SK8.wav";

const char* const strikes[] PROGMEM  = {
  strike1, strike2, strike3, strike4, strike5, strike6, strike7, strike8
};

int strike_time[8] = {779, 563, 687, 702, 673, 661, 666, 635};

const char strike_s1[] PROGMEM = "SKS1.wav";
const char strike_s2[] PROGMEM = "SKS2.wav";
const char strike_s3[] PROGMEM = "SKS3.wav";
const char strike_s4[] PROGMEM = "SKS4.wav";
const char strike_s5[] PROGMEM = "SKS5.wav";
const char strike_s6[] PROGMEM = "SKS6.wav";
const char strike_s7[] PROGMEM = "SKS7.wav";
const char strike_s8[] PROGMEM = "SKS8.wav";

const char* const strikes_short[] PROGMEM = {
  strike_s1, strike_s2, strike_s3, strike_s4,
  strike_s5, strike_s6, strike_s7, strike_s8
};
int strike_s_time[8] = {270, 167, 186, 250, 252, 255, 250, 238};

const char swing1[] PROGMEM = "SWS1.wav";
const char swing2[] PROGMEM = "SWS2.wav";
const char swing3[] PROGMEM = "SWS3.wav";
const char swing4[] PROGMEM = "SWS4.wav";
const char swing5[] PROGMEM = "SWS5.wav";

const char* const swings[] PROGMEM  = {
  swing1, swing2, swing3, swing4, swing5
};
int swing_time[8] = {389, 372, 360, 366, 337};

const char swingL1[] PROGMEM = "SWL1.wav";
const char swingL2[] PROGMEM = "SWL2.wav";
const char swingL3[] PROGMEM = "SWL3.wav";
const char swingL4[] PROGMEM = "SWL4.wav";

const char* const swings_L[] PROGMEM  = {
  swingL1, swingL2, swingL3, swingL4
};
int swing_time_L[8] = {636, 441, 772, 702};

char BUFFER[10];
// --------------------------------- SESLER ---------------------------------

void setup() {
  FastLED.addLeds<WS2811, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(100);  // ~LED şerit parlaklığının %40'ı
  setAll(0, 0, 0);             // ve kapatma

  Wire.begin();
  Serial.begin(9600);

  // ---- PİN AYARI ----
  pinMode(BTN, INPUT_PULLUP);
  pinMode(IMU_GND, OUTPUT);
  pinMode(SD_GND, OUTPUT);
  pinMode(BTN_LED, OUTPUT);
  digitalWrite(IMU_GND, 0);
  digitalWrite(SD_GND, 0);
  digitalWrite(BTN_LED, 1);
  // ---- PİN AYARI ----

  randomSeed(analogRead(2));    // rastgele oluşturucu için başlangıç noktası

  // IMU initialization
  accelgyro.initialize();
  accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
  accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  if (DEBUG) {
    if (accelgyro.testConnection()) Serial.println(F("MPU6050 Düzgün Çalışıyor"));
    else Serial.println(F("MPU6050 ÇALIŞMIYOR"));
  }

  // SD initialization
  tmrpcm.speakerPin = 9;
  tmrpcm.setVolume(5);
  tmrpcm.quality(1);
  if (DEBUG) {
    if (SD.begin(8)) Serial.println(F("SD Kart Düzgün Çalışıyor"));
    else Serial.println(F("SD Kart ÇALIŞMIYOR"));
  } else {
    SD.begin(8);
  }

  if ((EEPROM.read(0) >= 0) && (EEPROM.read(0) <= 5)) {  // ilk başlangıçta kontrol
    nowColor = EEPROM.read(0);   // rengi hatırlama
    HUMmode = EEPROM.read(1);    // modu hatırlama
  } else {                       // ilk başlangıç
    EEPROM.write(0, 0);          // varsayılana ayarla
    EEPROM.write(1, 0);          // varsayılana ayarla
    nowColor = 0;                // varsayılana ayarla
  }

  setColor(nowColor);
  byte capacity = voltage_measure();       // pil seviyesini al
  capacity = map(capacity, 100, 0, (NUM_LEDS / 2 - 1), 1);  // kılıç uzunluğuna dönüştür
  if (DEBUG) {
    Serial.print(F("Pil Seviyesi % "));
    Serial.println(capacity);
  }

  for (char i = 0; i <= capacity; i++) {   // pil seviyesini göster
    setPixel(i, red, green, blue);
    setPixel((NUM_LEDS - 1 - i), red, green, blue);
    FastLED.show();
    delay(25);
  }
  delay(1000);                         // pil seviyesini gösterme süresi (ms cinsinden)
  setAll(0, 0, 0);
  FastLED.setBrightness(BRIGHTNESS);   // parlak ayarla
}

// --- ANA DÖNGÜ---
void loop() {
  randomPULSE();
  getFreq();
  on_off_sound();
  btnTick();
  strikeTick();
  swingTick();
  batteryTick();
}
// --- ANA DÖNGÜ---

void btnTick() {
  btnState = !digitalRead(BTN);
  if (btnState && !btn_flag) {
    if (DEBUG) Serial.println(F("Buton Basma"));
    btn_flag = 1;
    btn_counter++;
    btn_timer = millis();
  }
  if (!btnState && btn_flag) {
    btn_flag = 0;
    hold_flag = 0;
  }
  // push the button
  if (btn_flag && btnState && (millis() - btn_timer > BTN_TIMEOUT) && !hold_flag) {
    ls_chg_state = 1;                     //  (on/off)
    hold_flag = 1;
    btn_counter = 0;
  }
  // ZAMAN AŞIMINDAN ÖNCE DÜĞMEYE BİRKAÇ KEZ BASILMIŞSA
  if ((millis() - btn_timer > BTN_TIMEOUT) && (btn_counter != 0)) {
    if (ls_state) {
      if (btn_counter == 3) {               // 3 time for color change
        nowColor++;                         // color change
        if (nowColor >= 6) nowColor = 0;
        setColor(nowColor);
        setAll(red, green, blue);
        eeprom_flag = 1;
      }
      if (btn_counter == 5) {               // 5 time for mode (Jedi-Sith mode)
        HUMmode = !HUMmode;
        if (HUMmode) {
          noToneAC();
          tmrpcm.play("HUM.wav");
        } else {
          tmrpcm.disable();
          toneAC(freq_f);
        }
        eeprom_flag = 1;
      }
    }
    btn_counter = 0;
  }
}

void on_off_sound() {
  if (ls_chg_state) {                
    if (!ls_state) {                 
      if (voltage_measure() > 10 || !BATTERY_SAFE) {
        if (DEBUG) Serial.println(F("KILIÇ AÇIK"));
        tmrpcm.play("ON.wav");
        delay(200);
        light_up();
        delay(200);
        bzzz_flag = 1;
        ls_state = true;               
        if (HUMmode) {
          noToneAC();
          tmrpcm.play("HUM.wav");
        } else {
          tmrpcm.disable();
          toneAC(freq_f);
        }
      } else {
        if (DEBUG) Serial.println(F("DÜŞÜK VOLTAJ!"));
        for (int i = 0; i < 5; i++) {
          digitalWrite(BTN_LED, 0);
          delay(400);
          digitalWrite(BTN_LED, 1);
          delay(400);
        }
      }
    } else {                         
      noToneAC();
      bzzz_flag = 0;
      tmrpcm.play("OFF.wav");
      delay(300);
      light_down();
      delay(300);
      tmrpcm.disable();
      if (DEBUG) Serial.println(F("KILIÇ KAPALI"));
      ls_state = false;
      if (eeprom_flag) {
        eeprom_flag = 0;
        EEPROM.write(0, nowColor);   // EEPROM'a renk yaz
        EEPROM.write(1, HUMmode);    // EEPROM'a mod yaz
      }
    }
    ls_chg_state = 0;
  }

  if (((millis() - humTimer) > 9000) && bzzz_flag && HUMmode) {
    tmrpcm.play("HUM.wav");
    humTimer = millis();
    swing_flag = 1;
    strike_flag = 0;
  }
  long delta = millis() - bzzTimer;
  if ((delta > 3) && bzzz_flag && !HUMmode) {
    if (strike_flag) {
      tmrpcm.disable();
      strike_flag = 0;
    }
    toneAC(freq_f,1);
    bzzTimer = millis();
  }
}

void randomPULSE() {
  if (PULSE_ALLOW && ls_state && (millis() - PULSE_timer > PULSE_DELAY)) {
    PULSE_timer = millis();
    PULSEOffset = PULSEOffset * k + random(-PULSE_AMPL, PULSE_AMPL) * (1 - k);
    if (nowColor == 0) PULSEOffset = constrain(PULSEOffset, -15, 5);
    redOffset = constrain(red + PULSEOffset, 0, 255);
    greenOffset = constrain(green + PULSEOffset, 0, 255);
    blueOffset = constrain(blue + PULSEOffset, 0, 255);
    setAll(redOffset, greenOffset, blueOffset);
  }
}

void strikeTick() {
  if ((ACC > STRIKE_THR) && (ACC < STRIKE_S_THR)) {
    if (!HUMmode) noToneAC();
    nowNumber = random(8);
    // PROGMEM'den parça adını oku
    strcpy_P(BUFFER, (char*)pgm_read_word(&(strikes_short[nowNumber])));
    tmrpcm.play(BUFFER);
    hit_flash();
    if (!HUMmode)
      bzzTimer = millis() + strike_s_time[nowNumber] - FLASH_DELAY;
    else
      humTimer = millis() - 9000 + strike_s_time[nowNumber] - FLASH_DELAY;
    strike_flag = 1;
  }
  if (ACC >= STRIKE_S_THR) {
    if (!HUMmode) noToneAC();
    nowNumber = random(8);
    // PROGMEM'den parça adını oku
    strcpy_P(BUFFER, (char*)pgm_read_word(&(strikes[nowNumber])));
    tmrpcm.play(BUFFER);
    hit_flash();
    if (!HUMmode)
      bzzTimer = millis() + strike_time[nowNumber] - FLASH_DELAY;
    else
      humTimer = millis() - 9000 + strike_time[nowNumber] - FLASH_DELAY;
    strike_flag = 1;
  }
}

void swingTick() {
  if (GYR > 80 && (millis() - swing_timeout > 100) && HUMmode) {
    swing_timeout = millis();
    if (((millis() - swing_timer) > SWING_TIMEOUT) && swing_flag && !strike_flag) {
      if (GYR >= SWING_THR) {      
        nowNumber = random(5);          
        // PROGMEM'den parça adını oku
        strcpy_P(BUFFER, (char*)pgm_read_word(&(swings[nowNumber])));
        tmrpcm.play(BUFFER);               
        humTimer = millis() - 9000 + swing_time[nowNumber];
        swing_flag = 0;
        swing_timer = millis();
        swing_allow = 0;
      }
      if ((GYR > SWING_L_THR) && (GYR < SWING_THR)) {
        nowNumber = random(5);            
        // PROGMEM'den parça adını oku
        strcpy_P(BUFFER, (char*)pgm_read_word(&(swings_L[nowNumber])));
        tmrpcm.play(BUFFER);              
        humTimer = millis() - 9000 + swing_time_L[nowNumber];
        swing_flag = 0;
        swing_timer = millis();
        swing_allow = 0;
      }
    }
  }
}

void getFreq() {
  if (ls_state) {                                               
    if (millis() - mpuTimer > 500) {                            
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);       

      // mutlak değeri bul ve 100'e böl
      gyroX = abs(gx / 100);
      gyroY = abs(gy / 100);
      gyroZ = abs(gz / 100);
      accelX = abs(ax / 100);
      accelY = abs(ay / 100);
      accelZ = abs(az / 100);

      // vektör toplamı
      ACC = sq((long)accelX) + sq((long)accelY) + sq((long)accelZ);
      ACC = sqrt(ACC);
      GYR = sq((long)gyroX) + sq((long)gyroY) + sq((long)gyroZ);
      GYR = sqrt((long)GYR);
      COMPL = ACC + GYR;
      /*
         // Hata Ayıklama IMU
         Serial.print("$");
         Serial.print(gyroX);
         Serial.print(" ");
         Serial.print(gyroY);
         Serial.print(" ");
         Serial.print(gyroZ);
         Serial.println(";");
      */
      freq = (long)COMPL * COMPL / 1500;                        // 
      freq = constrain(freq, 18, 300);                          
      freq_f = freq * k + freq_f * (1 - k);                     /
      mpuTimer = micros();                                     
    }
  }
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
}

void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}

void light_up() {
  for (char i = 0; i <= (NUM_LEDS / 2 - 1); i++) {        
    setPixel(i, red, green, blue);
    setPixel((NUM_LEDS - 1 - i), red, green, blue);
    FastLED.show();
    delay(25);
  }
}

void light_down() {
  for (char i = (NUM_LEDS / 2 - 1); i >= 0; i--) {      
    setPixel(i, 0, 0, 0);
    setPixel((NUM_LEDS - 1 - i), 0, 0, 0);
    FastLED.show();
    delay(25);
  }
}

void hit_flash() {
  setAll(255, 255, 255);            
  delay(FLASH_DELAY);                
  setAll(red, blue, green);        
}

void setColor(byte color) { //
  switch (color) {
    // 0 - red, 1 - green, 2 - blue, 3 - purple, 4 - yellow, 5 - ice blue
    case 0: //red
      red = 255;
      green = 0;
      blue = 0;
      break;
    case 1: //green
      red = 0;
      green = 0;
      blue = 255;
      break;
    case 2: //color: blue
      red = 0;
      green = 255;
      blue = 0;
      break;
    case 3: //color: purple
      red = 255;
      green = 0;
      blue = 255;
      break;
    case 4: //yellow
      red = 255;
      green = 255;
      blue = 0;
      break;
    case 5: //ice blue
      red = 0;
      green = 255;
      blue = 255;
      break;
  }
}

void batteryTick() {
  if (millis() - battery_timer > 30000 && ls_state && BATTERY_SAFE) {
    if (voltage_measure() < 15) {
      ls_chg_state = 1;
    }
    battery_timer = millis();
  }
}

byte voltage_measure() {
  voltage = 0;
  for (int i = 0; i < 10; i++) {    
    voltage += (float)analogRead(VOLT_PIN) * 5 / 1023 * (R1 + R2) / R2;
  }
  voltage = voltage / 10;           
  int volts = voltage / 3 * 100;    // 3 hücre!
  if (volts > 387)
    return map(volts, 420, 387, 100, 77);
  else if ((volts <= 387) && (volts > 375) )
    return map(volts, 387, 375, 77, 54);
  else if ((volts <= 375) && (volts > 368) )
    return map(volts, 375, 368, 54, 31);
  else if ((volts <= 368) && (volts > 340) )
    return map(volts, 368, 340, 31, 8);
  else if (volts <= 340)
    return map(volts, 340, 260, 8, 0);
}

And thats the scheme

Rubbish library. The error is because library creator used char* instead of const char*.

1 Like

Thank you so much. I solved that problem. I wrote the names of the sounds as

tmrpcm.play((char *)"HUM.wav")

The warnings stopped, but the sound is still as I have given in the link, and although the MPU6050 light is on, the sound does not change when I shake it.

The classic lightsaber sound is also absent.

Where do you think the problem might be?

video is private

So sorry. Please try again
https://youtube.com/shorts/9S9fjPlsX0U?feature=share

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.