package main import ( "fmt" "github.com/warthog618/gpio" "math" "time" ) const Timeout = math.MaxInt32 const TimeoutErrInitial string = "Timed out waiting for sensor's initial %s reading!" var oneSecondInCycles = (func() int { result := cyclesInAMillisecond() for i := 0; i < 100; i++ { result += cyclesInAMillisecond() } fmt.Println(result / 100) return result / 100 })() func cyclesInAMillisecond() int { count := 0 start := time.Now().UnixNano() for { count++ if time.Now().UnixNano() - start >= 1000000 { break } } return count } func main() { err := gpio.Open() if err != nil { panic(err) } defer gpio.Close() pinNumber := gpio.GPIO7 pin := gpio.NewPin(pinNumber) result, err := readDataFromDHT(pin) if err != nil { fmt.Println(fmt.Sprintf("Bad read! Reason: %s", err.Error())) } else { fmt.Println(result) } } func readDataFromDHT(pin *gpio.Pin) ([5]byte, error) { receivedInput := [5]byte{0, 0, 0, 0, 0} // Setup pin.PullUp() time.Sleep(time.Second) // Send start signal pin.Low() pin.Output() time.Sleep(1100 * time.Microsecond) pin.Input() time.Sleep(40 * time.Microsecond) // Get Data time.Sleep(80 * time.Microsecond) time.Sleep(80 * time.Microsecond) //if cyclesForReading(pin, gpio.Low) == Timeout { // return receivedInput, errors.New(fmt.Sprintf(TimeoutErrInitial, "low")) //} //if cyclesForReading(pin, gpio.High) == Timeout { // return receivedInput, errors.New(fmt.Sprintf(TimeoutErrInitial, "high")) //} // Store cycle number for each low and high pulse cycles := [80]int{} for i := 0; i < 80; i += 2 { cycles[i] = cyclesForReading(pin, gpio.Low) cycles[i + 1] = cyclesForReading(pin, gpio.High) } err := storeCycleCountsAsBinarySequence(&receivedInput, &cycles) if err != nil { return receivedInput, err } return receivedInput, nil } func storeCycleCountsAsBinarySequence(store *[5]byte, cycles *[80]int) error { for i := 0; i < 40; i++ { lowCycles := cycles[2 * i] highCycles := cycles[2 * i + 1] //if (lowCycles == Timeout) || (highCycles == Timeout) { // return errors.New("Timed out waiting for sensor pulse!") //} store[i / 8] <<= 1 if highCycles > lowCycles { store[i / 8] |= 1 } } return nil } func cyclesForReading(pin *gpio.Pin, level gpio.Level) int { count := 0 for pin.Read() == level { count++ if count >= oneSecondInCycles { return Timeout } } return count }