Is this ESP-IDF code OK?

erickchicat
Posts: 1
Joined: Sun Aug 04, 2019 1:37 am

Is this ESP-IDF code OK?

Postby erickchicat » Sun Aug 04, 2019 2:02 am

Someone can help me? I dont understand if this ok





/* GPIO Example

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
//gpio
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
//pwm
#include "driver/mcpwm.h"
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"

//adc
#include "driver/adc.h"
#include "driver/dac.h"
#include "esp_system.h"
#include "esp_adc_cal.h"

//uart
#include "esp_system.h"
#include "driver/uart.h"
#include "soc/uart_struct.h"
#include "esp_log.h"



#define GPIO_OUTPUT_IO_0 4
#define GPIO_OUTPUT_IO_1 5
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
#define GPIO_INPUT_IO_0 14
#define GPIO_INPUT_IO_1 13
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
#define ESP_INTR_FLAG_DEFAULT 0

//You can get these value from the datasheet of servo you use, in general pulse width varies between 1000 to 2000 mocrosecond
#define SERVO_MIN_PULSEWIDTH 1000 //Minimum pulse width in microsecond
#define SERVO_MAX_PULSEWIDTH 2000 //Maximum pulse width in microsecond
#define SERVO_MAX_DEGREE 90 //Maximum angle in degree upto which servo can rotate

// adc
#define DAC_EXAMPLE_CHANNEL 6
#define ADC2_EXAMPLE_CHANNEL 7

//uart
#define TXD_PIN (8)
#define RXD_PIN (9)

// la mayor parte de la logica se va en configuraciones , en mover punteros y optimizar memoria

static const int RX_BUF_SIZE = 1024;
static xQueueHandle gpio_evt_queue = NULL;

// UART
void init_uart(){
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);

}

// configurar los datos que va a enviar
int sendData(const char* logName, const char* data){
const int len = strlen(data);
const int txBytes = uart_write_bytes(UART_NUM_1, data, len);
ESP_LOGI(logName, "Wrote %d bytes", txBytes);
return txBytes;
}

static void tx_task(){
static const char *TX_TASK_TAG = "TX_TASK";
esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);

while(1){
// usa la funcion de arriba
sendData(TX_TASK_TAG, "Hello world");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}

static void rx_task(){
static const char *RX_TASK_TAG = "RX_TASK";
esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
// crea un espacio de memoria de 8 bits
// crea un espacio de memoria de 8 bits y te devuelve un apuntador al bloque de memoria alojado
uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);

while(1){
const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 1000 / portTICK_RATE_MS);
if(rxBytes){
data[rxBytes] = 0;
ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
}
}
free(data);
}


//pwm
static void mcpwm_example_gpio_initialize()
{
printf("initializing mcpwm servo control gpio......\n");
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 23); //Set GPIO 18 as PWM0A, to which servo is connected
}

static uint32_t servo_per_degree_init(uint32_t degree_of_rotation)
{
uint32_t cal_pulsewidth = 0;
cal_pulsewidth = (SERVO_MIN_PULSEWIDTH + (((SERVO_MAX_PULSEWIDTH - SERVO_MIN_PULSEWIDTH) * (degree_of_rotation)) / (SERVO_MAX_DEGREE)));
return cal_pulsewidth;
}

void mcpwm_example_servo_control(void *arg)
{
uint32_t angle, count;
//1. mcpwm gpio initialization
mcpwm_example_gpio_initialize();

//2. initial mcpwm configuration
printf("Configuring Initial Parameters of mcpwm......\n");
mcpwm_config_t pwm_config;
pwm_config.frequency = 50; //frequency = 50Hz, i.e. for every servo motor time period should be 20ms
pwm_config.cmpr_a = 0; //duty cycle of PWMxA = 0
pwm_config.cmpr_b = 0; //duty cycle of PWMxb = 0
pwm_config.counter_mode = MCPWM_UP_COUNTER;
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
//while (1) {
for (count = 0; count < SERVO_MAX_DEGREE; count++) {
printf("Angle of rotation: %d\n", count);
angle = servo_per_degree_init(count);
printf("pulse width: %dus\n", angle);
mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, angle);
vTaskDelay(10); //Add delay, since it takes time for servo to rotate, generally 100ms/60degree rotation at 5V
}
//}
}

// ADC-DAC
void adc_dac_control(void *arg){ //
uint8_t output_data = 0 ;
int read_raw;

esp_err_t readdata; // lo llama a una estructura
gpio_num_t adc_gpio_num, dac_gpio_num;

readdata = adc2_pad_get_io_num( ADC2_EXAMPLE_CHANNEL, &adc_gpio_num );
assert(readdata == ESP_OK );

readdata = dac_pad_get_io_num( DAC_EXAMPLE_CHANNEL, &dac_gpio_num );
assert( readdata == ESP_OK );

printf("ADC channel %d @ GPIO %d, DAC channel %d @ GPIO %d.\n", ADC2_EXAMPLE_CHANNEL, adc_gpio_num,
DAC_EXAMPLE_CHANNEL, dac_gpio_num );

dac_output_enable( DAC_EXAMPLE_CHANNEL );
printf("adc2_init...\n");
adc2_config_channel_atten( ADC2_EXAMPLE_CHANNEL, ADC_ATTEN_0db );

vTaskDelay(10 * portTICK_PERIOD_MS);

// comienza la conversion
printf("comienza la conversion....\n");
while(1){
dac_output_voltage( DAC_EXAMPLE_CHANNEL, output_data++ );
readdata = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, ADC_WIDTH_12Bit, &read_raw);
if ( readdata == ESP_OK ) {
printf("%d: %d\n", output_data, read_raw );
} else if ( readdata == ESP_ERR_INVALID_STATE ) {
printf("%s: ADC2 not initialized yet.\n", esp_err_to_name(readdata));
} else if ( readdata == ESP_ERR_TIMEOUT ) {
//This can not happen in this example. But if WiFi is in use, such error code could be returned.
printf("%s: ADC2 is in use by Wi-Fi.\n", esp_err_to_name(readdata));
} else {
printf("%s\n", esp_err_to_name(readdata));
}

vTaskDelay( 2 * portTICK_PERIOD_MS );
}
}


static void IRAM_ATTR gpio_isr_handler(void* arg) // ESTA FUNCION TOMA LOS VALORES DE LA ULTIMA FUNCION
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); // LO GUARDA EN EL QUEUE
}

static void gpio_task_example(void* arg) // LO RETOMA DEL QUEUE Y LO UTILIZA
{
uint32_t io_num; // ESTA ESTRUCTURA LA PODEMOS USAR , PARA COMPARAR CON GPIO
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));

if(io_num==GPIO_OUTPUT_IO_0){
gpio_set_level(GPIO_OUTPUT_IO_0,1); // on GPIO
}
else if(io_num==GPIO_OUTPUT_IO_1){
gpio_set_level(GPIO_OUTPUT_IO_0,0); // on GPIO
}
}

}
}

void app_main()
{
//OUTPUT!
gpio_config_t io_conf;
//disable interrupt
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf);

//interrupt of rising edge
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);

//change gpio intrrupt type for one pin
// gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));

//la primera opcion fue poner ciclos for
//puedes crear un swtich case para que cada sentencia se ejecute con un tiempo?!?!!


for(int i=0;i<=500;i++){
//start gpio task
switch(i){

case 20:
printf("Testing GPIO.......\n");
xTaskCreate(gpio_task_example, "gpio_task_example", 1024, NULL, 1, NULL);
break;

case 120:
// To create a servomotor hilo
printf("Testing servo motor.......\n");
xTaskCreate(mcpwm_example_servo_control, "mcpwm_example_servo_control", 1024, NULL, 2, NULL);
break;

case 200:
printf("Testing ADC/DAC.......\n");
xTaskCreate(adc_dac_control, "adc_dac_control", 1024, NULL, 3, NULL);
break;

case 300:
// uart
init_uart();
// se deben de crear dos taks uno para enviar y otro para recibir
printf("Testing uart.......\n");
xTaskCreate(rx_task, "uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL);
xTaskCreate(tx_task, "uart_tx_task", 1024*2, NULL, configMAX_PRIORITIES-1, NULL);
break;

default:
printf("this a default option \n");

}


}


}

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Is this ESP-IDF code OK?

Postby ESP_Sprite » Mon Aug 05, 2019 3:27 am

erickchicat wrote:
Sun Aug 04, 2019 2:02 am
Someone can help me? I dont understand if this ok
Dunno, have you tried compiling and running it yet? If that doesn't do what you expect, you now know the code is not OK. If it does, it probably is OK, dependent on your definition of 'OK'.

Who is online

Users browsing this forum: Baidu [Spider] and 125 guests