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