https://toitlang.org/ logo
Dhtxx exception error
# help
u
Deadline exceeded
Code:
Copy code
// Copyright (C) 2022 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the EXAMPLES_LICENSE file.

import dhtxx
import gpio

GPIO-PIN-NUM ::= 32

main:
  pin := gpio.Pin GPIO-PIN-NUM
  driver := dhtxx.Dht22 pin
  // On some versions of Toit/ESP-IDF it is necessary to sleep a bit before
  // reading the sensor for the first time.
  sleep --ms=300

  (Duration --s=1).periodic:
    print driver.read
f
From what I can see the wiring isn't correct. I can see multiple issues: - You mixed up the orientation of the DHT22 sensor. GND is connected to VCC, GND to VCC, ... - The + bus on the breadboard isn't connected to 3.3V. This (hopefully) saved your DHT22, as they are prone to burning out if connected the wrong way. That has happened multiple times on the DHT11, where the boards have different pin outs. - The DATA pin is connected to pin 17(?) and not 32 as you have in your code. The most important thing is to triple check the pinout of the DHT22 you have. It looks to me like it's just the sensor and not a module. If it has 4 pins that's likely the case. If it has 3, then it's guaranteed to be a module.
u
Thanks
And how can I make the sensor read first and export to datacake ,determine if value is more than 21 then do boo and if less do baa and doing 2 of this task simultaneously
Can I just use latch? Or just 1 task works
If latch works how can I loop doing task 1 then task 2 forever
f
Can you provide some pseudo code of what you are trying to do? Something like
Copy code
while true:
  read new temperature
  signal to others 
  sleep 5s
--
in parallel: 
- wait for new values, and upload each one to datacake
- blink led. If current value is below, blink fast otherwise slow
- ....
I'm pretty sure my example is not what you try to do, but if you provide your pseudo code I can probably figure out what you should use
u
This is how it should work: 1.sensor read 2.pubblish to datacake 3.determine value 4.if value >… then relay on
But this one does it only one time
🙁
Copy code
import datacake
import dhtxx
import gpio
import monitor
latch := monitor.Latch
sensor ::= 18

main:
  task:: producer-task-code
  task:: consumer-task-code
  
producer-task-code:
    client := datacake.connect
    pin := gpio.Pin sensor
    driver := dhtxx.Dht22 pin
    sleep --ms=3000
    result := driver.read-temperature
    temperature := datacake.Float "TEMPERATURE" --precision=1
    temperature.publish client result
    print "task one finished"
    latch.set result
consumer-task-code:
  temp := latch.get
  if temp == 21: print "led 1 on"
  if temp > 21:
    print "led 2 on"
f
A latch is something you can only set once. You can either use a channel (a pipe of fixed size), or a signal (which would just state that there is something somewhere, like in a shared variable/object).
u
Ok
Why it showed up the last error again? Of datacake
Jag pkg install won’t work
Copy code
sutida@MacBook-Air-khxng-pleng src % jag container install datacake service.toit -D datacake.api.token=f206ee24cf21ca04429ee472b1dbbe6054110822 -D datacake.device.id=esp32 -D datacake.product.slug=esp32-34
Installing container 'datacake' from 'service.toit' on 'wizardly-company' ...
/Users/sutida/Desktop/python main/project/.packages/github.com/kasperl/toit-datacake/0.1.2/package.lock:7:10: error: Package 'github.com/toitware/mqtt-2.1.1' not found
    url: github.com/toitware/mqtt
         ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/sutida/Desktop/python main/project/.packages/github.com/kasperl/toit-datacake/0.1.2/package.lock:11:10: error: Package 'github.com/toitware/toit-cert-roots-1.4.0' not found
    url: github.com/toitware/toit-cert-roots
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
service.toit:11:8: error: Package 'toit-cert-roots' for prefix 'certificate-roots' not found
import certificate_roots
       ^~~~~~~~~~~~~~~~~
service.toit:12:8: error: Package 'mqtt' for prefix 'mqtt' not found
import mqtt
       ^~~~
service.toit:13:8: error: Package 'mqtt' for prefix 'mqtt' not found
import mqtt.packets as mqtt
       ^~~~

Compilation failed
f
Maybe remove the api-token from the code here (or invalidate it on the datacake server). It's going to be copied to help.toit.io
u
How?
f
You should be able to edit posts in discord.
(just here)
can you print your pwd?
u
You mean directory?
f
I'm guessing you are inside
/Users/sutida/Desktop/python main/project/.packages/github.com/kasperl/toit-datacake/0.1.2/src
u
Yess
f
Not a good idea. The
.packages
directory is where the packages for your project are.
looking up the easiest way to run service for you. just a sec.
So the easiest is probably: create a datacake.toit in your project
/Users/sutida/Desktop/python main/project
. with the following content:
Copy code
import datacake.service

main:
  service.main
Then run that instead.
You are basically just calling the main from the service, but from within your project, where everything (dependencies...) are correctly set up.
If you run from withing something inside the
.packages
directory, it will think that the
.packages/github.com/kasperl/toit-datacake/0.1.2/
is its own project (which it fundamentally is). And that project isn't set up yet as nobody ran a
pkg install
there.
You can run the local
datacake.toit
with the same defines as you wrote above.
I would still obfuscate/replace the API-token in your code snippet, unless it's not valid.
u
Copy code
jag container install datacake datacake.toit -D datacake.api.token=f206ee24cf21ca04429ee472b1dbbe6054110822 -D datacake.device.id=esp32 -D datacake.product.slug=esp32-34
Installing container 'datacake' from 'datacake.toit' on 'wizardly-company' ...
<pkg:toit-datacake>/service.toit:69:7: error: Missing implementations for interface methods
class DatacakeServiceProvider extends ServiceProvider implements ServiceHandler:
      ^~~~~~~~~~~~~~~~~~~~~~~
<sdk>/system/services.toit:315:3: note: Missing implementation for 'handle'
  handle index/int arguments/any --gid/int --client/int -> any
  ^~~~~~
Compilation failed
It showed this
f
@kasperl does the package need updating?
Fwiw, datacake uses MQTT, so you could just talk directly to it too. The datacake package just makes things more elegant.
I will see if I can update the package this weekend.
I wouldn't be surprised if Kasper just didn't release the current version. Looking at the code, I don't see that problem. If you are up for it:
Copy code
git clone https://github.com/kasperl/toit-datacake.git
cd toit-datacake
jag pkg install
jag container install datacake src/service.toit -D ...
cd ..
In theory that would install the service from the latest sources. (Note that we can use the
service.toit
file directly this time, as we created a separate directory and did
pkg install
in it).
u
Are there any alternative to datacake that is easy to use?( In case which the new version didn't come in weekend)
f
For uploading data?
u
Yes
f
You have multiple options: google sheets, Supabase, Mqtt with Adafruit, ...
u
Google sheets?
f
If you want to. yes.
I haven't tried the tutorial in a while, but I think it should still work fine.
That's, obviously, not something you can use in production with 100s of devices, but if you just have a few devices at home, Google sheets is often easy.
u
I think I should try it
Is the updating time fast when compared to datacake?
f
Let me know if the tutorial needs updating. Maybe some button names or so (in the Google UI) have changed. I'm pretty sure the functionality is still there.
From the device's point of view, it just does an https post. That's pretty efficient.
u
how can i upload data to new row not replace row one to data?
on google sheets with toit
f
It should already do that:
sheet.appendRow([new Date(data.timestamp), data.temperature, data.humidity]);
appendRow
should add new rows.
u
it works now.
Copy code
esp.toit:4:8: error: Package for prefix 'certificate-roots' not found
import certificate_roots
f
did you install the package?
Copy code
jag pkg install github.com/toitware/toit-cert-roots@v1
u
I have just found new problem with dhtxx
When I was trying to read humidity then temperature into different variable it shows exception error
f
can you show the error?
u
Copy code
EXCEPTION error. 
insufficient signals from DHT
  0: Driver.read-data-no-catch_ <pkg:toit-dhtxx>/driver_.toit:128:7
  1: Driver.read-data_.<block>.<block>.<block>.<block> <pkg:toit-dhtxx>/driver_.toit:91:20
  2: Driver.read-data_.<block>.<block>.<block> <pkg:toit-dhtxx>/driver_.toit:89:32
  3: Task_.with-deadline_.<block> <sdk>/core/task.toit:223:16
  4: Task_.with-deadline_      <sdk>/core/task.toit:217:3
  5: with-timeout              <sdk>/core/utils.toit:189:24
  6: with-timeout              <sdk>/core/utils.toit:181:10
  7: Driver.read-data_.<block>.<block> <pkg:toit-dhtxx>/driver_.toit:89:9
  8: catch.<block>             <sdk>/core/exceptions.toit:124:10
  9: catch                     <sdk>/core/exceptions.toit:122:1
 10: catch                     <sdk>/core/exceptions.toit:73:10
 11: Driver.read-data_.<block> <pkg:toit-dhtxx>/driver_.toit:88:7
 12: SmallInteger_.repeat      <sdk>/core/numbers.toit:1288:3
 13: Driver.read-data_         <pkg:toit-dhtxx>/driver_.toit:87:14
 14: Driver.read-temperature   <pkg:toit-dhtxx>/driver_.toit:63:31
 15: main.<block>              test.toit:19:18
 16: Duration.of               <sdk>/core/time.toit:221:10
 17: Duration.periodic         <sdk>/core/time.toit:276:19
 18: main                      test.toit:17:20
****************
But when I use driver.read it works like normal
f
Apparently the esp32 wasn't able to receive data from the sensor. I think it usually tries 3 times, but apparently that didn't work.
Is this happening all the time?
u
Yes
f
interesting. Could you put a sleep between your first and second read?
maybe we are not giving the sensor enough time.
u
I am trying that.
f
Also: if you need both anyway, consider using
read
. That gives you a
DhtResult
which contains both values.
u
Oh it worked
I just need to sleep it for a little because sensor has a delayed time to read
f
Ok. So that means that we need to put some code in there to avoid reads that are too close (timewise) to each other.
As I said: use
read
(instead of
read-temperature
and
read-humidity
) to get both at the same time. Then you don't need any sleep.
u
But how can I store them in 2 different variables?
f
Copy code
result := sensor.read
temperature := result.temperature
humidity := result.humidity
u
Thanks
Are there any ways to round float.
f
Round how? (The initial "no" was a fat-finger response from Android)
u
So I need to stringtify it and cut it?
Like 20.1234566789737 to 20.12
f
So you want something like
to-string --fixed
? Unfortunately that's not implemented yet. A bit embarrassing, since I published a paper on how to do it efficiently...
The easiest is
(x * 100).to-int
or
.round
and then insert the dot. (Paying attention to the 0)
Alternatively I would just send the multiplied integer and let the Google sheet transform it back to a float
u
This rounded the output has no decimal (25.3830 to 25)
f
If you multiply with 100 first, you should have more digits than just 25.
u
Copy code
temp := driver.read-temperature
            temp2 := ((temp*10000).round)
            sleep --ms=500
            humid:= driver.read-humidity
            humid2 := ((humid*10000).round)
            print "$((temp2/10000).to-float) $((humid2/10000).to-float)"
25.0 53.0 25.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0 24.0 53.0
^^output
f
int/int -> int.
so you would need to
temp2/10000.0
.
but once you convert back to a float you will end up again with long numbers.
the current to-string algorithm doesn't pick the shortest string representation of a floating point number.
u
I turned it back Float because I need 2 decimals
f
as I said: just insert the dot.
u
Insert the dot?
f
Copy code
temp2 := (temp * 100).round
str := temp2.to-string
if temp2 != 0:
  str = "$(str[..str.size - 2]).$str[str.size - 2..]"
Or send the multiplied number to the server. If you don't need to print it right now, let Google sheets do the division.
u
Ok
Why does this code make relay on for ~~10 sec and off for 10 sec
Copy code
import http
import dhtxx
import gpio
import net
import certificate-roots
sensor ::= 18
relay-pump ::= 4
relay-fan ::= 5
URL ::= "https://script.google.com/macros/s/AKfycbzGpAen9NMdYgqbyilihGGVSC6IfYVyuz0mc-dlelItSFaq8DwnfSLUGZucXEEUdPFttw/exec"
main:
        pin := gpio.Pin sensor --output
        pump := gpio.Pin relay-pump --output
        fan := gpio.Pin relay-fan --output
        driver := dhtxx.Dht22 pin
        network := net.open
        client := http.Client.tls network
        certificate-roots.install-common-trusted-roots
        while true:
            sleep --ms=500
            temp := driver.read-temperature
            sleep --ms=500
            humid:= driver.read-humidity
            response := client.post-json --no-follow-redirects --uri=URL {"timestamp": Time.now.utc.to-iso8601-string,"temperature": temp,"humidity": humid,}
            if humid > 50:
                fan.set 1
                pump.set 0
                sleep --ms=11000
            if humid < 40 and temp > 29.4:
                pump.set 1
                fan.set 1
                sleep --ms=11000
            else:
                pump.set 0
                fan.set 0
                sleep --ms=11000
The conditions is second condition
f
Are you sure you don't need an
else if
for the
humid < 40
part? Currently, if the
humid > 50
you set the fan and sleep 10s. Then if checks for
humid < 40
which it isn't, and therefore enters the
else
branch, stopping the fan for 10s.
3 Views