QueueHandle_t xQueue;

void Task1(void *pvParameters) {
  int *p;
  while (1) {
    // Dynamically allocate memory for an integer
    p = (int *)pvPortMalloc(sizeof(int));
    *p = random(0, 100); // Generate a random number between 0 and 100
    
    // Attempt to send the pointer to the queue, wait indefinitely if needed
    if (xQueueSend(xQueue, &p, portMAX_DELAY) != pdPASS) {
      Serial.println("Failed to post to queue");
      vPortFree(p); // Free memory if message could not be sent to the queue
    }

    vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay for 1 second
  }
}

void Task2(void *pvParameters) {
  int *p;
  while (1) {
    // Wait to receive a pointer from the queue, wait indefinitely if needed
    if (xQueueReceive(xQueue, &p, portMAX_DELAY)) {
      Serial.print("Received: ");
      Serial.println(*p); // Print the received value
      vPortFree(p); // Free memory after processing
    }
  }
}

void setup() {
  Serial.begin(115200);

  // Create a queue capable of holding 10 integer pointers
  xQueue = xQueueCreate(10, sizeof(int *));
  
  if (xQueue == NULL) {
    Serial.println("Error creating the queue");
  }

  // Create two tasks pinned to core 1
  xTaskCreatePinnedToCore(Task1, "Task1", 10000, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(Task2, "Task2", 10000, NULL, 1, NULL, 1);
  
  vTaskDelete(NULL); // Delete the setup task to free memory
}

void loop() {
  // Empty loop since tasks are handled in FreeRTOS tasks
}