1
0

2 Revīzijas c6fb02938c ... 4f033ab38e

Autors SHA1 Ziņojums Datums
  Thomas Chef 4f033ab38e It works with sensor timing and sound 4 mēneši atpakaļ
  Thomas Chef 94fc196d40 Play a Mario tune 4 mēneši atpakaļ
5 mainītis faili ar 194 papildinājumiem un 62 dzēšanām
  1. 94 0
      import_midi.py
  2. 2 2
      main/CMakeLists.txt
  3. 36 6
      main/main.c
  4. 57 53
      main/sound.c
  5. 5 1
      main/sound.h

+ 94 - 0
import_midi.py

@@ -0,0 +1,94 @@
+import struct
+
+# Constants for MIDI to Frequency conversion
+A4_MIDI = 69
+A4_FREQ = 440.0
+
+def midi_to_freq(note):
+    return A4_FREQ * (2 ** ((note - A4_MIDI) / 12.0))
+
+def read_variable_length(data, index):
+    value = 0
+    while True:
+        byte = data[index]
+        index += 1
+        value = (value << 7) | (byte & 0x7F)
+        if not (byte & 0x80):
+            break
+    return value, index
+
+def parse_midi(filename):
+    with open(filename, 'rb') as f:
+        data = f.read()
+    
+    # Check MIDI header
+    if data[:4] != b'MThd':
+        raise ValueError("Invalid MIDI file")
+    
+    # Read header values
+    header_size = struct.unpack('>I', data[4:8])[0]
+    format_type, num_tracks, division = struct.unpack('>HHH', data[8:14])
+    index = 14 + (header_size - 6)
+
+    print("Header size:", header_size)
+    print("Format type:", format_type)
+    print("Number of tracks:", num_tracks)
+    print("Division:", division)
+
+    
+    notes = []
+    active_notes = {}
+    last_time = 0
+    
+    while index < len(data):
+        if data[index:index+4] == b'MTrk':
+            index += 4
+            track_length = struct.unpack('>I', data[index:index+4])[0]
+            index += 4
+            track_end = index + track_length
+            
+            while index < track_end:
+                delta_time, index = read_variable_length(data, index)
+                last_time += delta_time
+                event = data[index]
+                index += 1
+                
+                if event == 0xFF:  # Meta event
+                    meta_type = data[index]
+                    index += 1
+                    length, index = read_variable_length(data, index)
+                    index += length  # Skip meta event data
+                elif event >= 0x80:  # MIDI event
+                    status = event & 0xF0
+                    channel = event & 0x0F
+                    
+                    if status in (0x90, 0x80):  # Note On/Off
+                        note = data[index]
+                        velocity = data[index + 1]
+                        index += 2
+                        
+                        if status == 0x90 and velocity > 0:  # Note On
+                            active_notes[note] = last_time
+                        elif status == 0x80 or (status == 0x90 and velocity == 0):  # Note Off
+                            if note in active_notes:
+                                start_time = active_notes.pop(note)
+                                duration = last_time - start_time
+                                pause_duration = 0 if not notes else start_time - (notes[-1][1] + notes[-1][2])
+                                notes.append((midi_to_freq(note), int(duration), int(pause_duration)))
+                    else:
+                        index += 1  # Skip unknown event
+    
+    return notes
+
+def generate_c_array(notes):
+    c_code = "const struct Note notes[] = {\n"
+    for freq, duration, pause in notes:
+        c_code += f"    {{{freq:.2f}, {duration}, {pause}}},\n"
+    c_code += "};\n"
+    return c_code
+
+# Example usage
+midi_file = "track_1.mid"  # Replace with your MIDI file
+notes = parse_midi(midi_file)
+c_array = generate_c_array(notes)
+print(c_array)

+ 2 - 2
main/CMakeLists.txt

@@ -1,4 +1,4 @@
 idf_component_register(SRCS "sound.c" "main.c"
-
-                    INCLUDE_DIRS ".")
+                    INCLUDE_DIRS "."
+                    )
 

+ 36 - 6
main/main.c

@@ -3,6 +3,7 @@
 #include "freertos/task.h"
 #include "driver/gpio.h"
 #include "esp_log.h"
+#include <stdbool.h>
 #include "sdkconfig.h"
 #include "sound.h"
 
@@ -12,6 +13,8 @@
 #define BLINK_GPIO CONFIG_BLINK_GPIO
 #define PHOTO_SENSOR_PIN GPIO_NUM_18
 
+#define ACTIVE_THRESHOLD_MS 5000  // 60 seconds in milliseconds
+
 static void configure_led(void)
 {
     ESP_LOGI("LED", "Example configured to blink GPIO LED!");
@@ -34,21 +37,48 @@ void setup_photo_sensor() {
     ESP_LOGI("PHOTO", "Photomicrosensor configured on GPIO %d", PHOTO_SENSOR_PIN);
 }
 
+void check_sensor_active_time(bool fridgeDoorClosed) {
+
+    static int64_t activeStartTime = 0;
+
+    //ESP_EARLY_LOGI("CHECK", "State: %s", fridgeDoorClosed == true ? "CLOSED" : "OPEN");
+
+    if (fridgeDoorClosed == false) {
+        if (activeStartTime == 0) {
+            activeStartTime = esp_timer_get_time() / 1000; // Convert to milliseconds
+            ESP_LOGI("CHECK", "Door timer start time: %lld", activeStartTime);
+        } else {
+            int64_t elapsedTime = (esp_timer_get_time() / 1000) - activeStartTime;
+            //ESP_LOGI("CHECK", "Elapsed time: %lld", elapsedTime);
+            if (elapsedTime > ACTIVE_THRESHOLD_MS) {
+                enableNotificationSound(true);
+            }
+        }
+    } else {
+        activeStartTime = 0;
+        enableNotificationSound(false);
+    }
+}
+
 void read_photo_sensor_task(void *pvParameters) {
-    static int prevState = 0;
+    static bool prevState = false;
     while (1) {
-        int sensorState = gpio_get_level(PHOTO_SENSOR_PIN);
-        if (sensorState != prevState) {
-            prevState = sensorState;
-            ESP_EARLY_LOGI("PHOTO", "Triggered! State: %d", sensorState);
-            if( sensorState == 0 ) {
+        bool fridgeDoorClosed = gpio_get_level(PHOTO_SENSOR_PIN) == 0 ? false : true;
+        if (fridgeDoorClosed != prevState) {
+            prevState = fridgeDoorClosed;
+            ESP_EARLY_LOGI("PHOTO", "Triggered! State: %s", fridgeDoorClosed == true ? "CLOSED" : "OPEN");
+            if( fridgeDoorClosed == false ) {
                 gpio_set_level(BLINK_GPIO, 1);
             }
             else {
                 gpio_set_level(BLINK_GPIO, 0);
             }
         }
+
+        check_sensor_active_time(fridgeDoorClosed);
+
         vTaskDelay(pdMS_TO_TICKS(50)); // Delay 50ms (20 times per second)
+
     }
 }
 

+ 57 - 53
main/sound.c

@@ -2,79 +2,83 @@
 #include <stdio.h>
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
-#include "driver/gpio.h"
+//#include "driver/gpio.h"
 #include "esp_log.h"
 #include "sdkconfig.h"
-#include "driver/ledc.h"
+#include "driver/dac.h"
+#include "math.h"
 
-#define PWM_PIN       GPIO_NUM_19       // GPIO pin for PWM output
-#define PWM_FREQ      262               // Frequency for C4 (Middle C)
-#define PWM_CHANNEL   LEDC_CHANNEL_0
-#define PWM_TIMER     LEDC_TIMER_0
-#define PWM_RES       LEDC_TIMER_8_BIT  // 8-bit resolution (0-255)
+#define DAC_CHANNEL       1
+#define DAC_PIN           GPIO_NUM_25   // GPIO pin for DAC output GPIO25=Channel 1
+#define TONE_FREQ         440           // Frequency of the tone in Hz
+#define TONE_DURATION     1000          // Duration of the tone in ms
+#define QUIET_DURATION    1000          // Duration of the quiet period in ms
 
-static void setupSound() {
-
-    // Configure LEDC PWM Timer
-    ledc_timer_config_t timer_conf = {
-        .speed_mode = LEDC_LOW_SPEED_MODE,
-        .duty_resolution = PWM_RES,
-        .timer_num  = PWM_TIMER,
-        .freq_hz    = PWM_FREQ,
-        .clk_cfg    = LEDC_AUTO_CLK,
-    };
-    ledc_timer_config(&timer_conf);
-
-    // Configure LEDC PWM Channel
-    ledc_channel_config_t channel_conf = {
-        .gpio_num   = PWM_PIN,
-        .speed_mode = LEDC_LOW_SPEED_MODE,
-        .channel    = PWM_CHANNEL,
-        .timer_sel  = PWM_TIMER,
-        .duty       = 0,  // Start at 0% volume
-    };
-    ledc_channel_config(&channel_conf);
+bool soundEnabled = false;
 
-    ESP_LOGI("SOUND", "Sound setup");
-}
+static void play_tone(int frequency, float duration, int quietDuration) {
 
-static void sound_task(void *pvParameters) {
+    int semitones = 0;
 
-    setupSound();
+    int t_freq = frequency * pow(2.0, semitones / 12.0);
 
-    while (1) {
+    int8_t cw_offset = 0;
+    dac_cw_config_t cosineConf = {DAC_CHANNEL_1, DAC_CW_SCALE_8, DAC_CW_PHASE_0, t_freq, cw_offset};
 
-        ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL, 30);
-        ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL);
+    if (frequency == 0) {
+        dac_output_disable(DAC_CHANNEL_1);
+    } else {
+        dac_cw_generator_config(&cosineConf);
+        dac_output_enable(DAC_CHANNEL_1);
+    }
 
-        /*// Gradually increase volume (fade-in)
-        for (int duty = 10; duty <= 127; duty += 5) {
-            ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL, duty);
-            ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL);
-            vTaskDelay(pdMS_TO_TICKS(50));
-        }*/
+    // Loop with 50mS loops until the duration is complete
+    for(int i = 0; i < duration; i+=50) {
+        vTaskDelay(pdMS_TO_TICKS(50));
+        if( soundEnabled == false ) {
+            break;
+        }
+    }
+    dac_output_disable(DAC_CHANNEL_1);
+}
 
-        vTaskDelay(pdMS_TO_TICKS(1000));  // Keep sound for 500ms
+static void setupSound() {
 
-        ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL, 10);
-        ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL);
+    int8_t cw_offset = 0;
+    dac_cw_config_t cosineConf = {DAC_CHANNEL_1, DAC_CW_SCALE_8, DAC_CW_PHASE_0, 440, cw_offset};
 
-        /*// Gradually decrease volume (fade-out)
-        for (int duty = 127; duty >= 0; duty -= 5) {
-            ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL, duty);
-            ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_CHANNEL);
-            vTaskDelay(pdMS_TO_TICKS(50));
-        }*/
+    dac_output_disable(DAC_CHANNEL_1);
+    dac_cw_generator_config(&cosineConf);
+    dac_cw_generator_enable();
+    dac_output_disable(DAC_CHANNEL_1);
 
+    ESP_LOGI("SOUND", "Sound setup");
+}
 
-        vTaskDelay(pdMS_TO_TICKS(1000)); // Delay 1 second
-    }
+static void sound_task(void *pvParameters) {
 
     ESP_LOGI("SOUND", "Sound task starts....");
+
+    setupSound();
+
+    while (1) {
+        vTaskDelay(pdMS_TO_TICKS(1000));
+        if( soundEnabled ) {
+            play_tone(TONE_FREQ, TONE_DURATION, QUIET_DURATION);
+        }
+    }
 }
 
 void initSound() {
 
     xTaskCreate(sound_task, "sound_task", 2048, NULL, 10, NULL);
     ESP_LOGI("SOUND", "Sound initialized");
-}
+}
+
+void enableNotificationSound(bool enable)
+{
+    if (soundEnabled != enable) {
+        ESP_LOGI("SOUND", "Notification sound %s", enable ? "enabled" : "disabled");
+    }
+    soundEnabled = enable;
+}

+ 5 - 1
main/sound.h

@@ -1,2 +1,6 @@
 
-void initSound();
+#include <stdbool.h>
+
+void initSound();
+
+void enableNotificationSound(bool enable);