I will need to send and to receive data between pc and arduino in order to perform real time variable corrections, etc. to reach some bigger projects.
So, here it is the runnable code; the ucontroller part and the pc part.
(NOTICE: There is not mandatory to take a look to the microcontroller C code here, in order to test it, but it would be convenient:)
Code: Select all
CompilerIf 0
struct VectorInt16{int16_t x,y,z;};
struct DVectorInt16{VectorInt16 a,w;};
uint16_t disponible;
uint32_t baudios=115200;
struct recibido{byte ini[2];union {DVectorInt16 dato;float flotante[3];int32_t bit32[3];int16_t bit16[6];uint32_t ubit32[3];uint16_t ubit16[6];};}recibo;
void setup()
{
// inicializar comunicacion serial
Serial.begin(baudios);
while (!Serial); // espera para la enumeracion en el Leonardo, en los demas continua de inmediato
}
void loop()
{
if (disponible=Serial.available()>0 && Serial.readBytes(recibo.ini,14)>=14)
{
if ('o'==recibo.ini[0] && 'k'==recibo.ini[1]) // <- verificar si llegó bloque completo de dato
{
digitalWrite(7,1);
// enviar datos via RS232:
Serial.write("ok");
Serial.write((byte*)&recibo.dato,12);
delay(10); // <- ajustar este valor de la espera es crítico para poder enviar y recibir valores
digitalWrite(7,0);
}
else if ('b'==recibo.ini[0] && 'a'==recibo.ini[1]) // <- verificar si llegó baudios
{
while (Serial.available()&&Serial.read());Serial.flush(); // <- vaciar buffer
Serial.end();
baudios=recibo.ubit32[0];
delay(60);
setup();
}
}
else if ('r'==recibo.ini[0] && 'e'==recibo.ini[1]) // <- reset
{
digitalWrite(13,1);
while (Serial.available()&&Serial.read());Serial.flush(); // <- vaciar buffer
Serial.end();
delay(200) ;
recibo.ini[0]=0;
digitalWrite(13,0);
asm volatile (" jmp 0");
}
}
CompilerEndIf
Procedure.d EscalarRango(V.d,InputRangeL.d,InputRangeR.d,OutputRangeL.d,OutputRangeR.d)
;Interpola una variable V contenida dentro del rango no exponencial [InputRangeL,InputRangeR] hacia otro rango no exponencial [OutputRangeL,OutputRangeR]
;Util por ejemplo para barra de desplazamiento: TrackBarGadget()
If V<InputRangeL:V=InputRangeL:EndIf
If V>InputRangeR:V=InputRangeR:EndIf
ProcedureReturn OutputRangeL+(V-InputRangeL)*((OutputRangeR-OutputRangeL)/(InputRangeR-InputRangeL))
EndProcedure
Structure VectorInt16
x.w:y.w:z.w
EndStructure
Structure dVectorInt16
a.VectorInt16
w.VectorInt16
EndStructure
Enumeration gadgets
#ventanagadgets
#Menu
#contenedor
#cuadro
#puerto
#textosbarras
#botonenviar1
#botonenviar2
#botonenviar3
#s1
#s1fino
#s2
#s2fino
#s3
#s3fino
#e1
#e2
#e3
#e4
#e5
#e6
#s1min
#s1texto
#s1max
#s2min
#s2texto
#s2max
#s3min
#s3texto
#s3max
#e1texto
#e2texto
#e3texto
#e4texto
#e5texto
#e6texto
#trackbarmax=10000
#WindowWidth=800
#WindowHeight=600
EndEnumeration
Global s1.d,s1min.d=-#trackbarmax/2,s1max.d=#trackbarmax/2,s2.d,s2min.d=-#trackbarmax/2,s2max.d=#trackbarmax/2,s3.d,s3min.d=-#trackbarmax/2,s3max.d=#trackbarmax/2
Global e1.d,e2.d,e3.d,e4.d,e5.d,e6.d,e1min.d=-32768,e1max.d=32767,e2min.d=-32768,e2max.d=32767,e3min.d=-32768,e3max.d=32767,e4min.d=-32768,e4max.d=32767,e5min.d=-32768,e5max.d=32767,e6min.d=-32768,e6max.d=32767
;/ **************** serial ****************
Enumeration RS232
#serie
#puertosCOM
#baudios
EndEnumeration
Structure datosMPU6050
asci.a[2]
StructureUnion
dato.DVectorInt16
flotante.f[3]
bit32.l[3]
bit16.w[6]
ubit32.l[3]
ubit16.u[6]
EndStructureUnion
EndStructure
Procedure.a EnumSerial(Array puertos.a(1))
Protected i.a,c.a
For i=1 To 255
If QueryDosDevice_("COM"+Str(i),Space(128),128)
Redim puertos(c):puertos(c)=i:c+1
EndIf
Next
ProcedureReturn c
EndProcedure
Global Dim puertosRS232.a(0),npuertosserie.a=EnumSerial(puertosRS232())
If npuertosserie=0:MessageRequester("Error","No existen puertos RS232 disponibles"):End:EndIf
Global PuertoCOM$="",baudios.l
Global cantidad.q,leido.q; <- número de bytes reportados como disponibles para leer; número de bytes efectivamente leidos
#Nmuestra=79; <- número de muestras total (maximo 255)
Global nova.a
Global bloque.u=SizeOf(datosMPU6050); <- el bloque de datos recibidos desde el controlador por cada ciclo de programa de este
Global *baseserie.datosMPU6050=AllocateMemory(bloque*#Nmuestra,#PB_Memory_NoClear); la base de memoria donde se almacena una ristra de '#Nmuestra' bloques
Global *lecturavalida.datosMPU6050; <- puntero usado para gestionar la llegada de bloques leidos
DataSection
valoresbaudios:
Data.l 300,1200,2400,4800,9600,19200,38400,57600,74880,115200,230400,250000,500000,1000000,2000000
EndDatasection
Procedure vaciarserial(puerto.a=0)
Protected *nserie.byte,*serie.byte=AllocateMemory(10,#PB_Memory_NoClear)
cantidad=AvailableSerialPortInput(puerto)
While cantidad
*nserie.byte=ReAllocateMemory(*serie.byte,cantidad,#PB_Memory_NoClear):*serie=*nserie
ReadSerialPortData(puerto,*serie,cantidad)
cantidad=AvailableSerialPortInput(puerto)
Wend
FreeMemory(*serie.byte)
cantidad=0
EndProcedure
Procedure enviarserial(prefijo$="ok")
If PuertoCOM$
PokeS(*baseserie,prefijo$,2,#PB_Ascii)
if prefijo$="ok"
*baseserie\dato\a\x=2*s1:*baseserie\dato\a\y=2*s2:*baseserie\dato\a\z=2*s3
*baseserie\dato\w\x=4*s1:*baseserie\dato\w\y=4*s2:*baseserie\dato\w\z=4*s3
endif
WriteSerialPortData(#serie,*baseserie,bloque)
Delay(10)
EndIf
EndProcedure
Procedure.l recibirserial()
*lecturavalida=0
cantidad=AvailableSerialPortInput(#serie)
If cantidad=0
;sonido(39,99997)
nova+1
If nova>200:nova=0:CloseSerialPort(#serie):delay(100)
OpenSerialPort(#serie,PuertoCOM$,baudios,#PB_SerialPort_NoParity,8,0,#PB_SerialPort_NoHandshake,1024,8)
EndIf
;WriteSerialPortData(#serie,@"0",1)
ProcedureReturn 0
ElseIf cantidad>bloque*#Nmuestra; <- buffer rebosado: sin lectura
;sonido(89,10000)
vaciarserial(#serie):ProcedureReturn -2
ElseIf cantidad<>ReadSerialPortData(#serie,*baseserie,cantidad); <- error leyendo buffer
;sonido(229,77777)
vaciarserial(#serie):ProcedureReturn -1
Else
*lecturavalida=*baseserie
While *lecturavalida+bloque<=*baseserie+cantidad
If PeekS(*lecturavalida,2,#PB_Ascii)="ok"
ProcedureReturn cantidad
EndIf
*lecturavalida+1
Wend
*lecturavalida=0
;sonido(219,1077)
;WriteSerialPortData(#serie,@"+",1)
ProcedureReturn -3; <- sin lectura
EndIf
EndProcedure
;\ *******************************************
Procedure gachetos(x.u=20,y.u=20)
Protected gx.u=x+20,gy.u=y,sx.u,an.u=#WindowWidth*3/80,al.u=#WindowHeight*3/4
OpenWindow(#ventanagadgets,x,y,#WindowWidth,#WindowHeight,"",#PB_Window_SystemMenu|#PB_Window_BorderLess|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
CreateMenu(#Menu,WindowID(#ventanagadgets))
MenuTitle("Comportamiento botones de envio")
MenuItem(1,"Mantener enviando valor 1")
MenuItem(2,"Mantener enviando valor 2")
MenuItem(3,"Mantener enviando valor 3")
MenuItem(4,"Resetear uControlador")
FrameGadget(#cuadro,10,4,#WindowWidth-20,#WindowHeight-10,"Ajustar calibrado de motor")
;ScrollAreaGadget(#contenedor,gx+20,gy+40,#WindowWidth,#WindowHeight,#WindowWidth,#WindowHeight,10,#PB_ScrollArea_Flat)
TextGadget(#puerto,x,gy+4,80,20,"Puerto RS232:")
TextGadget(#textosbarras,gx+20,gy+36,#WindowWidth-20,20," s1 s1f s2 s2f s3 s3f e1 e2 e3 e4 e5 e6")
ComboBoxGadget(#puertosCOM,gx+60,gy,80,25):GadgetToolTip(#puertosCOM,"Puertos RS232 disponibles"); puerto COM
For s.a=0 To npuertosserie-1:AddGadgetItem(#puertosCOM,s,"COM"+Str(puertosRS232(s))):Next
ComboBoxGadget(#baudios,gx+140,gy,90,25); baudios
baudios.l=PeekL(?valoresbaudios+GetGadgetState(#baudios)*SizeOf(Long))
For s=1 To 15:Read.l a.l:AddGadgetItem(#baudios,-1,Str(a)+" baudio"):Next
TrackBarGadget(#s1,gx+20,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#s1,"dato 1 de salida")
StringGadget(#s1texto,gx,gy+500,90,20,Str(GetGadgetState(#s1)),#PB_String_UpperCase|#PB_Text_Center):GadgetToolTip(#s1texto,"dato 1 de salida")
ButtonGadget(#botonenviar1,gx,gy+540,90,20,"enviar 1",#PB_Button_Toggle):GadgetToolTip(#botonenviar1,"Pulsar para enviar dato 1")
StringGadget(#s1min,gx-10,gy+520,54,20,Str(0),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s1min,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s1min,"Valor mínimo")
StringGadget(#s1max,gx+48,gy+520,54,20,Str(#trackbarmax),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s1max,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s1max,"Valor máximo")
TrackBarGadget(#s1fino,gx+50,gy+50,an*2/3,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):SetGadgetState(#s1fino,(#trackbarmax-0)/2):GadgetToolTip(#s1fino,"salida 1 ajuste fino")
TrackBarGadget(#s2,gx+140,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#s2,"dato 2 de salida")
StringGadget(#s2texto,gx+120,gy+500,90,20,Str(GetGadgetState(#s2)),#PB_String_UpperCase|#PB_Text_Center):GadgetToolTip(#s2texto,"dato 2 de salida")
ButtonGadget(#botonenviar2,gx+120,gy+540,90,20,"enviar 2",#PB_Button_Toggle):GadgetToolTip(#botonenviar2,"Pulsar para enviar")
StringGadget(#s2min,gx+110,gy+520,54,20,Str(0),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s2min,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s2min,"Valor mínimo")
StringGadget(#s2max,gx+168,gy+520,54,20,Str(#trackbarmax),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s2max,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s2max,"Valor máximo")
TrackBarGadget(#s2fino,gx+170,gy+50,an*2/3,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):SetGadgetState(#s2fino,(#trackbarmax-0)/2):GadgetToolTip(#s2fino,"salida 2 ajuste fino")
TrackBarGadget(#s3,gx+260,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#s3,"dato 3 de salida")
StringGadget(#s3texto,gx+240,gy+500,90,20,Str(GetGadgetState(#s3)),#PB_String_UpperCase|#PB_Text_Center):GadgetToolTip(#s3texto,"dato 3 de salida")
ButtonGadget(#botonenviar3,gx+240,gy+540,90,20,"enviar 3",#PB_Button_Toggle):GadgetToolTip(#botonenviar3,"Pulsar para enviar")
StringGadget(#s3min,gx+230,gy+520,54,20,Str(0),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s3min,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s3min,"Valor mínimo")
StringGadget(#s3max,gx+288,gy+520,54,20,Str(#trackbarmax),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center):SetGadgetColor(#s3max,#PB_Gadget_BackColor,$456789):GadgetToolTip(#s3max,"Valor máximo")
TrackBarGadget(#s3fino,gx+290,gy+50,an*2/3,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):SetGadgetState(#s3fino,(#trackbarmax-0)/2):GadgetToolTip(#s3fino,"salida 3 ajuste fino")
TrackBarGadget(#e1,gx+400,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e1,"entrada 1")
StringGadget(#e1texto,gx+380,gy+500,64,20,Str(GetGadgetState(#e1)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
TrackBarGadget(#e2,gx+450,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e2,"entrada 2")
StringGadget(#e2texto,gx+430,gy+500,64,20,Str(GetGadgetState(#e2)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
TrackBarGadget(#e3,gx+500,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e3,"entrada 3")
StringGadget(#e3texto,gx+480,gy+500,64,20,Str(GetGadgetState(#e3)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
TrackBarGadget(#e4,gx+550,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e4,"entrada 4")
StringGadget(#e4texto,gx+530,gy+500,64,20,Str(GetGadgetState(#e4)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
TrackBarGadget(#e5,gx+600,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e5,"entrada 5")
StringGadget(#e5texto,gx+580,gy+500,64,20,Str(GetGadgetState(#e5)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
TrackBarGadget(#e6,gx+650,gy+50,an,al,0,#trackbarmax,#PB_TrackBar_Ticks|#PB_TrackBar_Vertical):GadgetToolTip(#e6,"entrada 6")
StringGadget(#e6texto,gx+630,gy+500,64,20,Str(GetGadgetState(#e6)),#PB_String_UpperCase|#PB_String_BorderLess|#PB_Text_Center)
SetGadgetState(#s1,EscalarRango(s1,s1min,s1max,0,#trackbarmax)):SetGadgetText(#s1texto,StrD(s1,6)):SetGadgetText(#s1min,StrD(s1min,4)):SetGadgetText(#s1max,StrD(s1max,4))
SetGadgetState(#s2,EscalarRango(s2,s2min,s2max,0,#trackbarmax)):SetGadgetText(#s2texto,StrD(s2,6)):SetGadgetText(#s2min,StrD(s2min,4)):SetGadgetText(#s2max,StrD(s2max,4))
SetGadgetState(#s3,EscalarRango(s3,s3min,s3max,0,#trackbarmax)):SetGadgetText(#s3texto,StrD(s3,6)):SetGadgetText(#s3min,StrD(s3min,4)):SetGadgetText(#s3max,StrD(s3max,4))
SetGadgetState(#e1,EscalarRango(e1,e1min,e1max,0,#trackbarmax)):SetGadgetText(#e1texto,StrD(e1,4))
SetGadgetState(#e2,EscalarRango(e2,e2min,e2max,0,#trackbarmax)):SetGadgetText(#e2texto,StrD(e2,4))
SetGadgetState(#e3,EscalarRango(e3,e3min,e3max,0,#trackbarmax)):SetGadgetText(#e3texto,StrD(e3,4))
SetGadgetState(#e4,EscalarRango(e4,e4min,e4max,0,#trackbarmax)):SetGadgetText(#e4texto,StrD(e4,4))
SetGadgetState(#e5,EscalarRango(e5,e5min,e5max,0,#trackbarmax)):SetGadgetText(#e5texto,StrD(e5,4))
SetGadgetState(#e6,EscalarRango(e6,e6min,e6max,0,#trackbarmax)):SetGadgetText(#e6texto,StrD(e6,4))
DisableGadget(#e1,1):DisableGadget(#e2,1):DisableGadget(#e3,1):DisableGadget(#e4,1):DisableGadget(#e5,1):DisableGadget(#e6,1)
DisableGadget(#e1texto,1):DisableGadget(#e2texto,1):DisableGadget(#e3texto,1):DisableGadget(#e4texto,1):DisableGadget(#e5texto,1):DisableGadget(#e6texto,1)
EndProcedure
gachetos()
baudios=115200:SetGadgetState(#baudios,9); <- 115200 baudios
Repeat
If #ventanagadgets=EventWindow()
evento=WaitWindowEvent()
et.i=EventType()
Select evento
Case #PB_Event_CloseWindow:End
Case #PB_Event_Menu
Select EventMenu()
Case 1:SetMenuItemState(#Menu,1,GetMenuItemState(#Menu,1)!1):SetGadgetState(#botonenviar1,GetMenuItemState(#Menu,1))
Case 2:SetMenuItemState(#Menu,2,GetMenuItemState(#Menu,2)!1):SetGadgetState(#botonenviar2,GetMenuItemState(#Menu,2))
Case 3:SetMenuItemState(#Menu,3,GetMenuItemState(#Menu,3)!1):SetGadgetState(#botonenviar3,GetMenuItemState(#Menu,3))
Case 4
baudios=115200:SetGadgetState(#baudios,9); <- 115200 baudios
PuertoCOM$=GetGadgetText(#puertosCOM)
If PuertoCOM$
If IsSerialPort(#serie)
enviarserial("re")
Delay(140)
; enviar dato de baudios nuevos
*baseserie\ubit32[0]=baudios
enviarserial("ba")
While IsSerialPort(#serie)
vaciarserial(#serie)
CloseSerialPort(#serie)
Wend
Delay(10)
EndIf
Delay(50)
If OpenSerialPort(#serie,PuertoCOM$,baudios,#PB_SerialPort_NoParity,8,0,#PB_SerialPort_NoHandshake,1024,8)
SetGadgetText(#cuadro,"Probando a través del puerto "+PuertoCOM$+" a "+Str(baudios)+" baudios")
vaciarserial(#serie)
Else
SetGadgetText(#cuadro,"No puede abrirse el puerto "+PuertoCOM$)
EndIf
EndIf
EndSelect
Case #PB_Event_Gadget
eg.i=EventGadget()
Select eg
Case #baudios,#puertosCOM
baudios.l=PeekL(?valoresbaudios+GetGadgetState(#baudios)*SizeOf(Long))
PuertoCOM$=GetGadgetText(#puertosCOM)
If PuertoCOM$
If IsSerialPort(#serie)
Delay(40)
; enviar dato de baudios nuevos
*baseserie\ubit32[0]=baudios
enviarserial("ba")
While IsSerialPort(#serie)
vaciarserial(#serie)
CloseSerialPort(#serie)
Wend
Delay(10)
EndIf
Delay(50)
If OpenSerialPort(#serie,PuertoCOM$,baudios,#PB_SerialPort_NoParity,8,0,#PB_SerialPort_NoHandshake,1024,8)
SetGadgetText(#cuadro,"Ajustar calibrado de motor a través del puerto "+PuertoCOM$+" a "+Str(baudios)+" baudios")
vaciarserial(#serie)
Else
SetGadgetText(#cuadro,"No puede abrirse el puerto "+PuertoCOM$)
EndIf
EndIf
Case #s1
s1=EscalarRango(GetGadgetState(#s1),0,#trackbarmax,s1min,s1max)
GadgetToolTip(#s1,StrD(s1,6)):SetGadgetText(#s1texto,StrD(s1,4))
Case #s1fino
Repeat
evento=WaitWindowEvent(100)
; usar aqui #WM_LBUTTONDOWN y #WM_LBUTTONUP
valor.d=GetGadgetState(#s1fino)/#trackbarmax-0.5
GadgetToolTip(#s1fino,StrD(valor,6))
s1+valor*(s1max-s1min)/#trackbarmax/3
If s1>s1max:s1=s1max:ElseIf s1<s1min:s1=s1min:EndIf
SetGadgetText(#s1texto,StrD(s1,4))
SetGadgetState(#s1,EscalarRango(s1,s1min,s1max,0,#trackbarmax))
GadgetToolTip(#s1,StrD(s1,6))
Until evento<>#PB_Event_GadgetDrop Or evento<>#PB_Event_LeftClick Or evento<>#PB_Event_Gadget Or evento<>#PB_Event_WindowDrop
evento=WaitWindowEvent()
If evento<>#PB_Event_Gadget:SetGadgetState(#s1fino,#trackbarmax/2):EndIf
Case #botonenviar1
If GetGadgetState(#botonenviar1):enviarserial():EndIf
If GetMenuItemState(#Menu,1)=0
SetGadgetState(#botonenviar1,0)
EndIf
Case #s2
s2=EscalarRango(GetGadgetState(#s2),0,#trackbarmax,s2min,s2max)
GadgetToolTip(#s2,StrD(s2,6)):SetGadgetText(#s2texto,StrD(s2,4))
Case #s2fino
Repeat
evento=WaitWindowEvent(100)
valor.d=GetGadgetState(#s2fino)/#trackbarmax-0.5
GadgetToolTip(#s2fino,StrD(valor,6))
s2+valor*(s2max-s2min)/#trackbarmax/3
If s2>s2max:s2=s2max:ElseIf s2<s2min:s2=s2min:EndIf
SetGadgetText(#s2texto,StrD(s2,4))
SetGadgetState(#s2,EscalarRango(s2,s2min,s2max,0,#trackbarmax))
GadgetToolTip(#s2,StrD(s2,6))
Until evento<>#PB_Event_GadgetDrop Or evento<>#PB_Event_LeftClick Or evento<>#PB_Event_Gadget Or evento<>#PB_Event_WindowDrop
evento=WaitWindowEvent()
If evento<>#PB_Event_Gadget:SetGadgetState(#s2fino,#trackbarmax/2):EndIf
Case #botonenviar2
If GetGadgetState(#botonenviar2):enviarserial():EndIf
If GetMenuItemState(#Menu,2)=0
SetGadgetState(#botonenviar2,0)
EndIf
Case #s3
s3=EscalarRango(GetGadgetState(#s3),0,#trackbarmax,s3min,s3max)
GadgetToolTip(#s3,StrD(s3,6)):SetGadgetText(#s3texto,StrD(s3,4))
Case #s3fino
Repeat
evento=WaitWindowEvent(100)
valor.d=GetGadgetState(#s3fino)/#trackbarmax-0.5
GadgetToolTip(#s3fino,StrD(valor,6))
s3+valor*(s3max-s3min)/#trackbarmax/3
If s3>s3max:s3=s3max:ElseIf s3<s3min:s3=s3min:EndIf
SetGadgetText(#s3texto,StrD(s3,4))
SetGadgetState(#s3,EscalarRango(s3,s3min,s3max,0,#trackbarmax))
GadgetToolTip(#s3,StrD(s3,6))
Until evento<>#PB_Event_GadgetDrop Or evento<>#PB_Event_LeftClick Or evento<>#PB_Event_Gadget Or evento<>#PB_Event_WindowDrop
evento=WaitWindowEvent()
If evento<>#PB_Event_Gadget:SetGadgetState(#s3fino,#trackbarmax/2):EndIf
Case #botonenviar3
If GetGadgetState(#botonenviar3):enviarserial():EndIf
If GetMenuItemState(#Menu,3)=0
SetGadgetState(#botonenviar3,0)
EndIf
Case #s1min
s1min=ValD(GetGadgetText(#s1min))
If s1min>s1max:s1min=s1max:SetGadgetText(#s1min,StrD(s1min,4)):EndIf
If s1min>s1:s1=s1min:EndIf
SetGadgetState(#s1,EscalarRango(s1,s1min,s1max,0,#trackbarmax))
SetGadgetText(#s1texto,StrD(s1,4))
Case #s1texto
; valor$=UCase(GetGadgetText(#s1texto))
; s.a=1
; While s<=Len(valor$)
; v.a=Asc(Mid(valor$,s,1))
; While v='.' Or v='E' Or v='-' Or (v>='0' And v<='9')
; s.a+1
; v.a=Asc(Mid(valor$,s,1))
; Wend
; valor$=RemoveString(valor$,Mid(valor$,s,1))
; Wend
; SetGadgetText(#s1texto,valor$)
s1=ValD(GetGadgetText(#s1texto))
If s1>s1max:s1=s1max:SetGadgetText(#s1texto,StrD(s1,4))
ElseIf s1<s1min:s1=s1min:SetGadgetText(#s1texto,StrD(s1,4))
EndIf
SetGadgetState(#s1,EscalarRango(s1,s1min,s1max,0,#trackbarmax))
Case #s1max
s1max=ValD(GetGadgetText(#s1max))
If s1max<s1min:s1max=s1min:SetGadgetText(#s1max,StrD(s1max,4)):EndIf
If s1max<s1:s1=s1max:EndIf
SetGadgetState(#s1,EscalarRango(s1,s1min,s1max,0,#trackbarmax))
SetGadgetText(#s1texto,StrD(s1,4))
Case #s2min
s2min=ValD(GetGadgetText(#s2min))
If s2min>s2max:s2min=s2max:SetGadgetText(#s2min,StrD(s2min,4)):EndIf
If s2min>s2:s2=s2min:EndIf
SetGadgetState(#s2,EscalarRango(s2,s2min,s2max,0,#trackbarmax))
SetGadgetText(#s2texto,StrD(s2,4))
Case #s2texto
s2=ValD(GetGadgetText(#s2texto))
If s2>s2max:s2=s2max:SetGadgetText(#s2texto,StrD(s2,4))
ElseIf s2<s2min:s2=s2min:SetGadgetText(#s2texto,StrD(s2,4))
EndIf
SetGadgetState(#s2,EscalarRango(s2,s2min,s2max,0,#trackbarmax))
Case #s2max
s2max=ValD(GetGadgetText(#s2max))
If s2max<s2min:s2max=s2min:SetGadgetText(#s2max,StrD(s2max,4)):EndIf
If s2max<s2:s2=s2max:EndIf
SetGadgetState(#s2,EscalarRango(s2,s2min,s2max,0,#trackbarmax))
SetGadgetText(#s2texto,StrD(s2,4))
Case #s3min
s3min=ValD(GetGadgetText(#s3min))
If s3min>s3max:s3min=s3max:SetGadgetText(#s3min,StrD(s3min,4)):EndIf
If s3min>s3:s3=s3min:EndIf
SetGadgetState(#s3,EscalarRango(s3,s3min,s3max,0,#trackbarmax))
SetGadgetText(#s3texto,StrD(s3,4))
Case #s3texto
s3=ValD(GetGadgetText(#s3texto))
If s3>s3max:s3=s3max:SetGadgetText(#s3texto,StrD(s3,4))
ElseIf s3<s3min:s3=s3min:SetGadgetText(#s3texto,StrD(s3,4))
EndIf
SetGadgetState(#s3,EscalarRango(s3,s3min,s3max,0,#trackbarmax))
Case #s3max
s3max=ValD(GetGadgetText(#s3max))
If s3max<s3min:s3max=s3min:SetGadgetText(#s3max,StrD(s3max,4)):EndIf
If s3max<s3:s3=s3max:EndIf
SetGadgetState(#s3,EscalarRango(s3,s3min,s3max,0,#trackbarmax))
SetGadgetText(#s3texto,StrD(s3,4))
Case #contenedor
;If et=#PB_EventType_Resize:EndIf
EndSelect
If GetGadgetState(#botonenviar1) Or GetGadgetState(#botonenviar2) Or GetGadgetState(#botonenviar3)
enviarserial()
EndIf
;
If PuertoCOM$
recibirserial()
If *lecturavalida
e1=*lecturavalida\dato\a\x:e2=*lecturavalida\dato\a\y:e3=*lecturavalida\dato\a\z:e4=*lecturavalida\dato\w\x:e5=*lecturavalida\dato\w\y:e6=*lecturavalida\dato\w\z
SetGadgetState(#e1,EscalarRango(e1,e1min,e1max,0,#trackbarmax)):GadgetToolTip(#e1,StrD(e1,6)):SetGadgetText(#e1texto,StrD(e1,4))
SetGadgetState(#e2,EscalarRango(e2,e2min,e2max,0,#trackbarmax)):GadgetToolTip(#e2,StrD(e2,6)):SetGadgetText(#e2texto,StrD(e2,4))
SetGadgetState(#e3,EscalarRango(e3,e3min,e3max,0,#trackbarmax)):GadgetToolTip(#e3,StrD(e3,6)):SetGadgetText(#e3texto,StrD(e3,4))
SetGadgetState(#e4,EscalarRango(e4,e4min,e4max,0,#trackbarmax)):GadgetToolTip(#e4,StrD(e4,6)):SetGadgetText(#e4texto,StrD(e4,4))
SetGadgetState(#e5,EscalarRango(e5,e5min,e5max,0,#trackbarmax)):GadgetToolTip(#e5,StrD(e5,6)):SetGadgetText(#e5texto,StrD(e5,4))
SetGadgetState(#e6,EscalarRango(e6,e6min,e6max,0,#trackbarmax)):GadgetToolTip(#e6,StrD(e6,6)):SetGadgetText(#e6texto,StrD(e6,4))
EndIf
EndIf
EndSelect
EndIf
ForEver