SinCosTan Equation

This program was my attempt to plot a given equation on a VGA screen using Prof. Hunter Adam's VGA Library for the RaspberryPi Pico. The resources for the project include the C SDK User Guide, the RP2040 Datasheet and Prof. Hunter's website.


The Equation

I chose the following equation to plot on the VGA screen:

\begin{align} sin(cos(tan(xy))) = sin(cos(tan(x))) + sin(cos(tan(y))) \end{align}

Using desmos, the plotted equation looks as shown.

The plot of the equation on Desmos

The complete code

/*
 * Parth Sarthi Sharma (pss242@cornell.edu)
 * Code based on examples from Raspberry Pi Foundation.
 * This code is an implementation of a custom sin cos tan function
 * on the Raspberry Pi Pico to draw a pattern.
 */
#include <stdio.h> //The standard C library
#include <math.h> //The standard math library
#include "pico/stdlib.h" //Standard library for Pico
#include "hardware/pio.h" //The hardware PIO library
#include "hardware/dma.h" //The hardware DMA library
#include "pico/time.h" //The pico time library
#include "hardware/gpio.h" //The hardware GPIO library
#include "pico/multicore.h" //The pico multicore library
#include "vga_graphics.h" //The graphics library

#define HEIGHT 480 //Height of the VGA screen
#define WIDTH 640 //Width of the VGA screen

void core1_entry() { //The program running on core 1
    double error = 0.01, step = 0.01, x, y, ans; //The error, step, x coordiante, y coordinate and the answer variables
    for(x = 0; x < 5; x += step){ //For x in range [0, 5) with 0.01 step size
        for(y = 4; y > -4; y -= step){ //For y in range (-4, 4] with 0.01 step size
            ans = sin(cos(tan(x * y))) - sin(cos(tan(x))) - sin(cos(tan(y))); //Solve for the equation
            if((ans < error) && (ans > -error)){ //If the solution is within the given error limits
                fillCircle((50 * x) + (WIDTH / 2), (HEIGHT / 2) - (50 * y), 1, RED); //Draw a red circle to create an enlarged image
            }
        }
    }
}

int main(){ //The program running on core 0
    double error = 0.01, step = 0.01, x, y, ans; //The error, step, x coordiante, y coordinate and the answer variables

    stdio_init_all(); //Initialize all of the present standard stdio types that are linked into the binary
    initVGA(); //Initialize the VGA screen and functions
    multicore_launch_core1(core1_entry); //Reset core1 and enter the core1_entry function on core 1 using the default core 1 stack

    for(x = -5; x < 0; x += step){ //For x in range [-5, 0) with 0.01 step size
        for(y = 4; y > -4; y -= step){ //For y in range (-4, 4] with 0.01 step size
            ans = sin(cos(tan(x * y))) - sin(cos(tan(x))) - sin(cos(tan(y))); //Solve for the equation
            if((ans < error) && (ans > -error)){ //If the solution is within the given error limits
                fillCircle((50 * x) + (WIDTH / 2), (HEIGHT / 2) - (50 * y), 1, RED); //Draw a red circle to create an enlarged image
            }
        }
    }
}


Code Organization

The code has a VGA library which has been explained really nicely by Prof. Adams and the main file.

The main crux of the program lies in the fact that I needed to compute the equation within a given error as trying to find the exact solution can be really computationally expensive. Therefore, I divided the x-coordinates and the y-coordinates into a series of small steps and computed the equation on using those coordinates. If the answer is within the given error limit, draw a red circle at the given location.


The output

Plotting the equation on RaspberryPi Pico

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(SinCosTan-project)

pico_sdk_init()

add_executable(SinCosTan)

pico_enable_stdio_usb(SinCosTan 1)
pico_enable_stdio_uart(SinCosTan 1)

pico_generate_pio_header(SinCosTan ${CMAKE_CURRENT_LIST_DIR}/hsync.pio)
pico_generate_pio_header(SinCosTan ${CMAKE_CURRENT_LIST_DIR}/vsync.pio)
pico_generate_pio_header(SinCosTan ${CMAKE_CURRENT_LIST_DIR}/rgb.pio)

target_sources(SinCosTan PRIVATE SinCosTan.c vga_graphics.c)

target_link_libraries(SinCosTan PRIVATE pico_stdlib hardware_pio hardware_dma hardware_adc hardware_irq pico_time pico_multicore)

pico_add_extra_outputs(SinCosTan)