11#include "wifi_connectivity.h"
2+
23#include "esp_log.h"
34#include "esp_err.h"
45
3839#define BLINK_PERIOD 1000
3940
4041#define LEDC_MODE LEDC_LOW_SPEED_MODE
41- #define LEDC_DUTY_RES LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
42- #define LEDC_TIMER LEDC_TIMER_0
43- #define LEDC_FREQUENCY 350 // Frequency in Hertz. Set frequency at 4 kHz
42+ #define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 13-bit duty (0–8191)
43+ #define LEDC_TIMER LEDC_TIMER_0
44+ #define LEDC_FREQUENCY 20000 // 20 kHz for DRV8833
45+
46+ //DRV8833 input pins
47+ //Motor A (left): IN1, IN2
48+ #define MOTOR_A_IN1_GPIO GPIO_NUM_16 // DRV8833 IN1 (forward)
49+ #define MOTOR_A_IN2_GPIO GPIO_NUM_18 // DRV8833 IN2 (reverse)
4450
45- //YELLOW IS LEFT MOTOR, WHITE IS RIGHT MOTOR
46- #define LEDC_OUTPUT_IO1 18// Define the output GPIO
47- #define LEDC_OUTPUT_IO2 16 // Define the output GPIO
51+ //Motor B (right): IN3, IN4
52+ #define MOTOR_B_IN1_GPIO GPIO_NUM_12 // DRV8833 IN3 (forward)
53+ #define MOTOR_B_IN2_GPIO GPIO_NUM_11 // DRV8833 IN4 (reverse)
54+
55+ //LEDC channels – 2 per motor (fwd/rev)
56+ #define LEDC_CH_A_FWD LEDC_CHANNEL_0
57+ #define LEDC_CH_A_REV LEDC_CHANNEL_1
58+ #define LEDC_CH_B_FWD LEDC_CHANNEL_2
59+ #define LEDC_CH_B_REV LEDC_CHANNEL_3
4860
49- #define LEDC_CHANNEL1 LEDC_CHANNEL_0
50- #define LEDC_CHANNEL2 LEDC_CHANNEL_1
5161
5262#define FADE_RESOLUTION 10
5363
@@ -77,11 +87,13 @@ static bool charging;
7787static bool inGame ;
7888static bool resetting ;
7989
80- // used to decide when we start reversing or moving forward and such
90+ // used to decide when we start reversing or moving forward and such (THIS WAS FOR ESC)
91+ /*
8192static uint8_t lowerReverseBound = 16;
8293static uint8_t upperReverseBound = 49;
8394static uint8_t lowerForwardBound = 56;
8495static uint8_t upperForwardBound = 89;
96+ */
8597
8698TaskHandle_t doMovementHandle = NULL ;
8799bool finishedMoving = false;
@@ -563,111 +575,153 @@ float getPercentFromRawDuty(float duty)
563575 return (duty * 100 )/(pow (2 , LEDC_DUTY_RES ));
564576}
565577
566- //from the direction going from -100 to 100, gets actual duty value needed to send to the motors
567- float getRawDutyFromBaseDirection (float duty )
578+ // Convert -100..100 "direction" into a raw duty magnitude for PWM
579+ // Sign (positive/negative) is handled separately in move()
580+ float getRawDutyFromBaseDirection (float dir )
568581{
569- //if duty is positive, remember valid values are from 86 - 100. If negative, from 36-50
570- uint8_t range = upperReverseBound - lowerReverseBound ;
571- //if positive movement
572- if (duty > 1 )
573- {
574- //first get it between 0 and 1, then multiple to get in the forward range, then add by lower bound to get a range between loewr and upper bound.
575- //this keeps it in the correct range 56 to 89
576- duty /= 100.0 ;
577- duty *= range ;
578- duty += lowerForwardBound ;
579- }
580- // if negative movement
581- else if (duty < -1 )
582- {
583- //first limit it to the range -1 to 0 by dividing by (100 / range)
584- duty /= 100.0 ;
585- //then put it in the correct range from say -33 to 0 by multiplying by range
586- duty *= range ;
587- //now, add 33 to put it in the range 0 and 33, and then add 16 to put it in the range 16 to 49
588- duty += range + lowerReverseBound ;
589- }
590- // meaning movement is roughly 0, so set it to 53 which makes it about 0.
591- else
592- {
593- duty = 53 ;
594- }
595- //now that we have correct duty cycle numbers, get specifically the raw duty
596- return getRawDutyFromPercent (duty );
582+ float mag = fabsf (dir ); // 0..100
583+ if (mag < 1.0f ) {
584+ return 0.0f ; // treat tiny values as stop
585+ }
586+ if (mag > 100.0f ) {
587+ mag = 100.0f ; // clamp
588+ }
589+ return getRawDutyFromPercent (mag );
597590}
598591
592+
599593//converts pulse width (in ms) to the proper duty cycle RAW. Not sure if this is right, may have to check
600594float convertPulseWidthToPercentDuty (int pulseWidth )
601595{
602596 //get it with pulse width over period. Convert from microseconds to seconds too.
603597 return pulseWidth /(pow (10 , 6 )/LEDC_FREQUENCY ) * 100 ;
604598}
605599
606- // sets up the PWM pins and timer
607600static void ledc_setup (){
608- // Timer Configuration
609- gpio_reset_pin (LEDC_OUTPUT_IO1 );
610- gpio_set_direction (LEDC_OUTPUT_IO1 , GPIO_MODE_OUTPUT );
611- gpio_reset_pin (LEDC_OUTPUT_IO2 );
612- gpio_set_direction (LEDC_OUTPUT_IO2 , GPIO_MODE_OUTPUT );
613-
614- ledc_timer_config_t timer_conf = {
615- .speed_mode = LEDC_MODE ,
616- .duty_resolution = LEDC_DUTY_RES ,
617- .timer_num = LEDC_TIMER ,
618- .freq_hz = LEDC_FREQUENCY ,
619- .clk_cfg = LEDC_AUTO_CLK
620- };
621- ESP_ERROR_CHECK (ledc_timer_config (& timer_conf ));
622- // Channel Configuration
623- ledc_channel_config_t channel_conf1 = {
624- .speed_mode = LEDC_MODE ,
625- .channel = LEDC_CHANNEL1 ,
626- .timer_sel = LEDC_TIMER ,
627- .intr_type = LEDC_INTR_DISABLE ,
628- .gpio_num = LEDC_OUTPUT_IO1 ,
629- .duty = 0 ,
630- .hpoint = 0
631- };
632- ESP_ERROR_CHECK (ledc_channel_config (& channel_conf1 ));
633-
634- //Channel Configuration
635- ledc_channel_config_t channel_conf2 = {
636- .speed_mode = LEDC_MODE ,
637- .channel = LEDC_CHANNEL2 ,
638- .timer_sel = LEDC_TIMER ,
639- .intr_type = LEDC_INTR_DISABLE ,
640- .gpio_num = LEDC_OUTPUT_IO2 ,
641- .duty = 0 ,
642- .hpoint = 0
643- };
644- ESP_ERROR_CHECK (ledc_channel_config (& channel_conf2 ));
645-
646- //50 means neither moves
647- uint8_t startPos = 50 ;
648- //Move the left motor to start position
649- ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CHANNEL1 , startPos / 100.0 * pow (2 , LEDC_DUTY_RES )));
650- ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CHANNEL1 ));
651-
652- //Move the right motor
653- ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CHANNEL2 , startPos / 100.0 * pow (2 , LEDC_DUTY_RES )));
654- ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CHANNEL2 ));
601+ // Timer configuration – shared by all channels
602+ ledc_timer_config_t timer_conf = {
603+ .speed_mode = LEDC_MODE ,
604+ .duty_resolution = LEDC_DUTY_RES ,
605+ .timer_num = LEDC_TIMER ,
606+ .freq_hz = LEDC_FREQUENCY ,
607+ .clk_cfg = LEDC_AUTO_CLK
608+ };
609+ ESP_ERROR_CHECK (ledc_timer_config (& timer_conf ));
610+
611+ // Motor A – forward (IN1)
612+ ledc_channel_config_t ch_a_fwd = {
613+ .speed_mode = LEDC_MODE ,
614+ .channel = LEDC_CH_A_FWD ,
615+ .timer_sel = LEDC_TIMER ,
616+ .intr_type = LEDC_INTR_DISABLE ,
617+ .gpio_num = MOTOR_A_IN1_GPIO ,
618+ .duty = 0 ,
619+ .hpoint = 0
620+ };
621+ ESP_ERROR_CHECK (ledc_channel_config (& ch_a_fwd ));
622+
623+ // Motor A – reverse (IN2)
624+ ledc_channel_config_t ch_a_rev = {
625+ .speed_mode = LEDC_MODE ,
626+ .channel = LEDC_CH_A_REV ,
627+ .timer_sel = LEDC_TIMER ,
628+ .intr_type = LEDC_INTR_DISABLE ,
629+ .gpio_num = MOTOR_A_IN2_GPIO ,
630+ .duty = 0 ,
631+ .hpoint = 0
632+ };
633+ ESP_ERROR_CHECK (ledc_channel_config (& ch_a_rev ));
634+
635+ // Motor B – forward (IN3)
636+ ledc_channel_config_t ch_b_fwd = {
637+ .speed_mode = LEDC_MODE ,
638+ .channel = LEDC_CH_B_FWD ,
639+ .timer_sel = LEDC_TIMER ,
640+ .intr_type = LEDC_INTR_DISABLE ,
641+ .gpio_num = MOTOR_B_IN1_GPIO ,
642+ .duty = 0 ,
643+ .hpoint = 0
644+ };
645+ ESP_ERROR_CHECK (ledc_channel_config (& ch_b_fwd ));
646+
647+ // Motor B – reverse (IN4)
648+ ledc_channel_config_t ch_b_rev = {
649+ .speed_mode = LEDC_MODE ,
650+ .channel = LEDC_CH_B_REV ,
651+ .timer_sel = LEDC_TIMER ,
652+ .intr_type = LEDC_INTR_DISABLE ,
653+ .gpio_num = MOTOR_B_IN2_GPIO ,
654+ .duty = 0 ,
655+ .hpoint = 0
656+ };
657+ ESP_ERROR_CHECK (ledc_channel_config (& ch_b_rev ));
658+
659+ // Start with everything stopped
660+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_FWD , 0 ));
661+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_FWD ));
662+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_REV , 0 ));
663+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_REV ));
664+
665+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_FWD , 0 ));
666+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_FWD ));
667+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_REV , 0 ));
668+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_REV ));
655669}
656670
657- void move (){
658- //Move the left motor
659- ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CHANNEL1 , getRawDutyFromBaseDirection (currentDirection [0 ])));
660- ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CHANNEL1 ));
661671
662- //Move the right motor
663- ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CHANNEL2 , getRawDutyFromBaseDirection (currentDirection [1 ])));
664- ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CHANNEL2 ));
672+ void move (){
673+ // Left motor = motor A
674+ float dirA = currentDirection [0 ]; // -100..100
675+ float dutyA = getRawDutyFromBaseDirection (dirA );
676+
677+ if (fabsf (dirA ) < 1.0f ) {
678+ // Stop: both inputs low -> coast
679+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_FWD , 0 ));
680+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_FWD ));
681+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_REV , 0 ));
682+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_REV ));
683+ } else if (dirA > 0 ) {
684+ // Forward: PWM on IN1, IN2 low
685+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_FWD , (uint32_t )dutyA ));
686+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_FWD ));
687+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_REV , 0 ));
688+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_REV ));
689+ } else {
690+ // Reverse: PWM on IN2, IN1 low
691+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_FWD , 0 ));
692+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_FWD ));
693+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_A_REV , (uint32_t )dutyA ));
694+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_A_REV ));
695+ }
665696
666- //ACTUAL DUTIES ARE: 56-89 FOR FORWARD (INCLUSIVE)
667- //AND THEN 16 TO 49 FOR REVERSE (INCLUSIVE), 16 IS FASTER THAN 49
697+ // Right motor = motor B
698+ float dirB = currentDirection [1 ];
699+ float dutyB = getRawDutyFromBaseDirection (dirB );
700+
701+ if (fabsf (dirB ) < 1.0f ) {
702+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_FWD , 0 ));
703+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_FWD ));
704+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_REV , 0 ));
705+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_REV ));
706+ } else if (dirB > 0 ) {
707+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_FWD , (uint32_t )dutyB ));
708+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_FWD ));
709+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_REV , 0 ));
710+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_REV ));
711+ } else {
712+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_FWD , 0 ));
713+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_FWD ));
714+ ESP_ERROR_CHECK (ledc_set_duty (LEDC_MODE , LEDC_CH_B_REV , (uint32_t )dutyB ));
715+ ESP_ERROR_CHECK (ledc_update_duty (LEDC_MODE , LEDC_CH_B_REV ));
716+ }
668717
718+ // Now:
719+ // - (IN1,IN2) = (PWM,0) → forward with PWM
720+ // - (IN1,IN2) = (0,PWM) → reverse with PWM
721+ // - (0,0) → coast
669722}
670723
724+
671725//just quickly putting the on-chip LED to high
672726void doBlink ()
673727{
@@ -677,7 +731,74 @@ void doBlink()
677731 gpio_set_level (BLINK_GPIO , s_led_state );
678732}
679733
734+ void app_main (void )
735+ {
736+ //blink so we know the ESP32 booted
737+ //doBlink();
738+ //vTaskDelay(pdMS_TO_TICKS(500));
739+
740+ //set up PWM for the DRV8833 motor driver
741+ ledc_setup ();
742+ move ();
743+
744+
745+ while (1 ) {
746+
747+ //both motors forward (about 40% power)
748+ currentDirection [0 ] = 40 ; //left motor
749+ currentDirection [1 ] = 40 ; //right motor
750+ move ();
751+ ESP_LOGI ("MOTOR_TEST" , "Forward" );
752+ vTaskDelay (pdMS_TO_TICKS (2000 ));
753+
754+
755+ //stop
756+ currentDirection [0 ] = 0 ;
757+ currentDirection [1 ] = 0 ;
758+ move ();
759+ ESP_LOGI ("MOTOR_TEST" , "Stop" );
760+ vTaskDelay (pdMS_TO_TICKS (1500 ));
761+
762+
763+ //both motors reverse
764+ currentDirection [0 ] = -40 ;
765+ currentDirection [1 ] = -40 ;
766+ move ();
767+ ESP_LOGI ("MOTOR_TEST" , "Reverse" );
768+ vTaskDelay (pdMS_TO_TICKS (2000 ));
769+
770+ //spin in place (left fwd, right rev)
771+ currentDirection [0 ] = 40 ; // Left forward
772+ currentDirection [1 ] = -40 ; // Right reverse
773+ move ();
774+ ESP_LOGI ("MOTOR_TEST" , "Spin in place" );
775+ vTaskDelay (pdMS_TO_TICKS (2000 ));
776+
777+ //stop again
778+ currentDirection [0 ] = 0 ;
779+ currentDirection [1 ] = 0 ;
780+ move ();
781+ ESP_LOGI ("MOTOR_TEST" , "Stop" );
782+ vTaskDelay (pdMS_TO_TICKS (1500 ));
783+ }
784+
785+ }
786+
787+
788+ //for testing the goalpost mechanism only
789+ /*
790+ void app_main() {
791+ //blink LED to know if booted
792+ doBlink();
793+ vTaskDelay(pdMS_TO_TICKS(1000));
794+
795+ //only running the goalpost mechanism
796+ goalpost_mechanism_init(); // <- this never returns (has while(true))
797+ }
798+ */
799+
680800//where the program initially starts
801+ /*
681802void app_main() {
682803 //allocate space for struct, initially set everything to false
683804 moveStruct = malloc(sizeof(Movement));
@@ -700,3 +821,4 @@ void app_main() {
700821
701822 vTaskDelay(pdMS_TO_TICKS(500));
702823}
824+ */
0 commit comments