# Professor Cristiano Teixeira
# Sob Licença Apache 2.0

print("INICIO")
from machine import Pin, PWM, ADC, SPI
import time
import math

#Função que faz a conversão de um valor nesse programa nem usei, mas tá aí.
def map(valor, de_min, de_max, para_min, para_max):
    # Verifica se o valor está fora da faixa de entrada
    if valor < de_min:
        valor = de_min
    elif valor > de_max:
        valor = de_max
    # Calcula o valor mapeado
    de_variacao = de_max - de_min
    para_variacao = para_max - para_min
    valor_mapeado = int((valor - de_min) * para_variacao / de_variacao + para_min)
    return valor_mapeado

#Função para converter os valores do joystick em graus
def joystick_to_angle(horizontal, vertical):
    # Ajustar os valores para que o centro seja (0, 0)
    x = 512 - horizontal
    y = vertical - 512  # Inverter o eixo y para corresponder à orientação desejada
    # Calcular o ângulo em radianos
    angle_radians = math.atan2(x, y)
    # Converter o ângulo para graus
    angle_degrees = math.degrees(angle_radians)
    # Ajustar o ângulo para que 0 graus seja na posição desejada
    if angle_degrees < 0:
        angle_degrees += 360
    return angle_degrees
    #Esse funcionou.

# instruções para testes para ver se os valores estavam indo certo
'''def teste():
    horizontal = 512
    vertical = 1024
    print(joystick_to_angle(horizontal, vertical))  # Deve imprimir 0.0

    horizontal = 0
    vertical = 512
    print(joystick_to_angle(horizontal, vertical))  # Deve imprimir 90.0

    horizontal = 512
    vertical = 0
    print(joystick_to_angle(horizontal, vertical))  # Deve imprimir 180.0

    horizontal = 1024
    vertical = 512
    print(joystick_to_angle(horizontal, vertical))  # Deve imprimir 270.0
'''

# Declaramos os pinos  
j1_ve = ADC(Pin(12))
j1_ho = ADC(Pin(13))
j1_bt = Pin(14, Pin.IN)
CLK_PIN	= Pin(18, Pin.OUT)
DATA_PIN = Pin(19, Pin.OUT)
CS_PIN = Pin(5, Pin.OUT)
# configuração das pinagens do motor
direcao=Pin(15,Pin.OUT)
passo=Pin(2,Pin.OUT) 

# configuração de direção da rotação
DIR = 1 # direção do movimento:  0 = anti-horário, 1 = horário 
direcao.value(DIR) # Seta a direção para horário

# Variáveis Globais
ante_ve = 2048
ante_ho = 2048
graus = 0
angulo = 0
atual = 0
destino = 0 

# Move o motor uma quantidade x de passos, também nem usei, mas vou deixar de modelo
def passos (x):
    for cont in range (x):
        # para dar 1 passo, precisa intercalar um LIGADO e um DESLIGADO na sequência
        # Cada combinação equivale a 1 passo, com intervalo de 100 milésimos de segundo
        passo.value(1)
        passo.value(0)

# Move o motor para x graus
def graus(x):
    passos=int(x/1.8)
    print(passos)
    for cont in range (passos):
        # para dar 1 passo, precisa intercalar um LIGADO e um DESLIGADO na sequência
        # Cada combinação equivale a 1 passo, com intervalo de 100 milésimos de segundo
        passo.value(1)
        passo.value(0)

# Move o motor sempre em sentido horário
def sentidohorario(angulo):
    global atual
    print("Atual:", atual)
    if (angulo > atual):
        destino = angulo - atual
        DIR = 1 # direção do movimento:  0 = anti-horário, 1 = horário 
    else:
        destino = atual - angulo
        DIR = 0 # direção do movimento:  0 = anti-horário, 1 = horário 
    direcao.value(DIR) # Seta a direção
    print("Destino:", destino)
    atual=angulo
    passos=int(destino/1.8)
    for cont in range (passos):
        # para dar 1 passo, precisa intercalar um LIGADO e um DESLIGADO na sequência
        # Cada combinação equivale a 1 passo, com intervalo de 100 milésimos de segundo
        passo.value(1)
        passo.value(0)
        time.sleep(0.1)

# Move o motor para a posição com a menor quantidade de passos possível
def seta(angulo):
    global atual
    #print("Atual:", atual)
    # Calcula a diferença de ângulo nos dois sentidos
    horario = (angulo - atual) % 360
    antihorario = (atual - angulo) % 360
    # Escolhe a direção com o menor número de passos
    if horario <= antihorario:
        destino = horario
        DIR = 1 # direção do movimento: 1 = horário
    else:
        destino = antihorario
        DIR = 0 # direção do movimento: 0 = anti-horário
    direcao.value(DIR) # Seta a direção
    #print("Destino:", destino)
    atual = angulo
    passos = int(destino / 1.8)
    for cont in range(passos):
        # para dar 1 passo, precisa intercalar um LIGADO e um DESLIGADO na sequência
        # Cada combinação equivale a 1 passo, com intervalo de 100 milésimos de segundo
        passo.value(1)
        passo.value(0)
        time.sleep(0.01)

# Instruções de teste
'''def teste2(): 
    print("Vai para 90")
    seta(90)
    time.sleep(3)
    print("Vai para 180")
    seta(180)
    time.sleep(3)
    print("Volta para 90")
    seta(90)
    time.sleep(3)
    print("Vai para 270")
    seta(270)
    time.sleep(3)
    print("Volta para 0")
    seta(0)
    time.sleep(3)
'''

# Criamos as variáveis que irão receber os valores. Sei que não precisa, mas é para fins didáticos.
vj1_ve=0 
vj1_ho=0

while True:
    #fiz a conversão dos valores lidos de 0 à 4095 para 0 à 1024 apenas por conveniência de já ensinar os valores de leituras analógicos assim no arduino
    vj1_ve=map(j1_ve.read(), 0, 4095, 0, 1024)
    vj1_ho=map(j1_ho.read(), 0, 4095, 0, 1024)

    if (j1_bt.value() == 0):
        print("Pépe já tirei a vela!")
    
    if (vj1_ho != ante_ho or vj1_ve != ante_ve):
        if (vj1_ho == 512 and vj1_ve ==512):
            #print("parado")
            seta(0)
        else:
            angulo=joystick_to_angle(vj1_ho, vj1_ve)
            print("H:",vj1_ho)
            print("V:",vj1_ve)
            print(angulo)
            seta(angulo)
        ante_ho=vj1_ho
        ante_ve=vj1_ve

    #time.sleep(0.1)
A4988