Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Me estoy volviendo loco ya y necesito ayuda. Estoy intentando programar el sensor Dallas DS18S20, que usa el bus 1-Wire. Doy por hecho que la conexión está bien, pero pongo una foto por si acaso.
Pues no consigo ni reiniciarlo, se supone que poniendo el nivel bajo el bus durante 500us, al ponerlo como entrada debería de mantenerse bajo durante 60us, pero no se pone bajo ni a palos.
He probado de mil maneras y nada. A ver si alguien que lo haya hecho ve algo que haga mal o que no haga.
Public Sub InitDS18S20()
Dim PinLogicLevel As Byte
Dim n As Byte
Call PutPin(SensorPin, bxInputTristate) ' pin en entrada
Call PutPin(SensorPin, bxOutputLow) ' pin bajo
Delay(500.0E-6) ' mantiene el pulso 500 microsegundos
Call PutPin(SensorPin, bxInputTristate) ' pin en entrada
Delay(60.0E-6) ' he probado diversos tiempos de espera
PinLogicLevel = GetPin(SensorPin) ' pero no da cero: (
Debug.Print Cstr(PinLogicLevel)
End Sub
He probado todo tipo de tiempos antes de la lectura, pequeños, grandes, e incluso sin él y siempre está en alto. Lo que pasa es que se quedó ese tiempo la última vez antes de copiar el código.
De todos modos yo creo que incluso ese tiempo debería servir, porque al parecer es el tiempo mínimo de presencia de pulso, y antes hay una pequeña espera. Pongo la documentación y la imagen.
INITIALIZATION PROCEDURE—RESET AND PRESENCE PULSES
All communication with the DS18S20 begins with an initialization sequence that consists of a reset pulse
from the master followed by a presence pulse from the DS18S20. This is illustrated in Figure 10. When
the DS18S20 sends the presence pulse in response to the reset, it is indicating to the master that it is on
the bus and ready to operate.
During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus
low for a minimum of 480µs. The bus master then releases the bus and goes into receive mode (RX).
When the bus is released, the 5kO pullup resistor pulls the 1-Wire bus high. When the DS18S20 detects
this rising edge, it waits 15µs to 60µs and then transmits a presence pulse by pulling the 1-Wire bus low
for 60µs to 240µs.
Te aconsejaría que te agencies un osciloscopio si no lo tienes. Si no puedes comprobarlo empezarás a dudar de todo y es una de las peores cosas que te puede ocurrir.
Saludos.
Te aconsejaría que te agencies un osciloscopio si no lo tienes. Si no puedes comprobarlo empezarás a dudar de todo y es una de las peores cosas que te puede ocurrir.
Xactamente. isotopo, lo que dice Juanjo es lo más sensato.
Ya he conseguido solucionarlo. En realidad seguramente que enviaba bien el pulso de reset, pero no era capaz de recibir el pulso bajo, ni todavía sé porqué. El caso es que al utilizar una función del BasicX24 llamada RCTime, que precisamente pone el pin en entrada y calcula el tiempo que dura un pulso, obtengo 90us de bajada, como debe ser.
Lo demás fijándome en otros programas no ha sido muy complicado, dejo el código de prueba a modo de "hola mundo" para la posteridad.
Option Explicit
Const SensorPin As Byte = 20
'-------------------------------------------------
' Main
'-------------------------------------------------
Public Sub Main()
Call Reset()
Call Comando(&hCC) ' Saltar la ROM
Call Comando(&h44) ' iniciar conversion temperatura
Call Reset()
Call Comando(&hCC) ' Saltar la ROM
Dim GradosCentigrados As Single
GradosCentigrados = LeerTemperatura( SensorPin )
Debug.Print Cstr(GradosCentigrados); "º"
End Sub
'-------------------------------------------------
'Resetea el DS1820
'-------------------------------------------------
Public Sub Reset()
Dim TimeDelay As Single
Call PulseOut(SensorPin, 600.0E-6, 0)
Call RCTime(SensorPin, 0, TimeDelay)
' Debug.Print Cstr(TimeDelay) ' obtengo 90us
End Sub
'-------------------------------------------------
' Lee la temperatura del sensor
'-------------------------------------------------
public Function LeerTemperatura(byVal busPin as Byte) As Single
dim temperature as Single
dim dataLsb as Byte, dataMsb as Byte
Call Comando(&hBE) ' proceder a leer la temperatura
dataLsb = LeerByte(SensorPin)
dataMsb = LeerByte(SensorPin)
' Verificar temperatura negativa
if (GetBit (dataMsb, 7) = 1) then
temperature = (CSng (dataMsb xor 255) * 256.0) + _
CSng (dataLsb xor 255) + 1.0
else
temperature = (CSng (dataMsb) * 256.0) + CSng (dataLsb)
end if
LeerTemperatura = temperature / 2.0
End Function
'-------------------------------------------------
' envia un comando
'-------------------------------------------------
Public Sub Comando(ByVal Comando As Byte)
Dim i As byte
For i = 0 To 7
Call Put1Wire(SensorPin, GetBit(Comando, i)) ' comando recibir la temperatura
Next
End Sub
'-------------------------------------------------
' Lee un Byte del bus
'-------------------------------------------------
Public Function LeerByte(ByVal Pin As Byte) As Byte
Dim Dato As Byte
LeerByte = 0
Dim i As Byte
For i = 0 To 7
Call PutBit(LeerByte, i, Get1Wire(Pin))
Next
End Function
Es verdad que podría haberlo verificado con el osciloscopio y me hubiera evitado muchas horas de quebraderos, me lo plantearé en un futuro el conseguir uno. He leído algo acerca de poder fabricar uno usando la entrada de la tarjeta de sonido y a lo mejor para mi nivel no necesitaría más de momento. ¿qué os parece el asunto?.