Arduino software: "request for member 'read11' in 'sensor', which is of non-class type 'DHT()'" - arduino-uno

Im getting this error message with my arduino code "request for member 'read11' in 'sensor', which is of non-class type 'DHT()'"
#include <DHT.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int greenPin = A0;
DHT sensor();
void setup()
{
lcd.begin(16,2); //16 by 2 character display
}
void loop()
{
delay(1000); //wait a sec (recommended for DHT11)
sensor.read11(greenPin);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Humidity = ");
lcd.print(sensor.humidity);
lcd.setCursor(0,1);
lcd.print("Temp = ");
lcd.print(sensor.temperature);
}
I have downloaded the library it said to download, please help!
I took it from this website btw just to avoid copywright issues:
https://www.hive-rd.com/blog/arduino-dht11-output-lcd-module/

At the line
DHT sensor();
the use of parenthesis causes this line to get parsed as a forward declaration of a function sensor(), taking no arguments, returning type DHT. What you want is to just define sensor as a variable with type dht (note:
the tutorial uses lower case.) The correct syntax would be:
#include <dht.h>
/* code */
dht sensor;
If you refer to the tutorial you linked, you'll see that's how it appears in the code example.

Related

How to optimize SYCL kernel

I'm studying SYCL at university and I have a question about performance of a code.
In particular I have this C/C++ code:
And I need to translate it in a SYCL kernel with parallelization and I do this:
#include <sycl/sycl.hpp>
#include <vector>
#include <iostream>
using namespace sycl;
constexpr int size = 131072; // 2^17
int main(int argc, char** argv) {
//Create a vector with size elements and initialize them to 1
std::vector<float> dA(size);
try {
queue gpuQueue{ gpu_selector{} };
buffer<float, 1> bufA(dA.data(), range<1>(dA.size()));
gpuQueue.submit([&](handler& cgh) {
accessor inA{ bufA,cgh };
cgh.parallel_for(range<1>(size),
[=](id<1> i) { inA[i] = inA[i] + 2; }
);
});
gpuQueue.wait_and_throw();
}
catch (std::exception& e) { throw e; }
So my question is about c value, in this case I use directly the value two but this will impact on the performance when I'll run the code? I need to create a variable or in this way is correct and the performance are good?
Thanks in advance for the help!
Interesting question. In this case the value 2 will be a literal in the instruction in your SYCL kernel - this is as efficient as it gets, I think! There's the slight complication that you have an implicit cast from int to float. My guess is that you'll probably end up with a float literal 2.0 in your device assembly. Your SYCL device won't have to fetch that 2 from memory or cast at runtime or anything like that, it just lives in the instruction.
Equally, if you had:
constexpr int c = 2;
// the rest of your code
[=](id<1> i) { inA[i] = inA[i] + c; }
// etc
The compiler is almost certainly smart enough to propagate the constant value of c into the kernel code. So, again, the 2.0 literal ends up in the instruction.
I compiled your example with DPC++ and extracted the LLVM IR, and found the following lines:
%5 = load float, float addrspace(4)* %arrayidx.ascast.i.i, align 4, !tbaa !17
%add.i = fadd float %5, 2.000000e+00
store float %add.i, float addrspace(4)* %arrayidx.ascast.i.i, align 4, !tbaa !17
This shows a float load & store to/from the same address, with an 'add 2.0' instruction in between. If I modify to use the variable c like I demonstrated, I get the same LLVM IR.
Conclusion: you've already achieved maximum efficiency, and compilers are smart!

Where can I find documentation on SPI2STATbits?

I've recently come across spi2statbits in the following function:
int WriteSPI2( int data)
{
int f;
SPI2BUF = data; // write to buffer for TX
while( !SPI2STATbits.SPIRBF)
{f=1;}// wait transfer completion
return SPI2BUF; // read the received value
} // WriteSPI2
I'm using the above in conjunction with a PIC24FJ128GA010 project.
I've been searching around to find more about SPI2STATbits but haven't found actual documentation. I assume this is a fairly basic requirement.
Can someone direct me to the correct documentation?
See page 130 of the datasheet , look for SPIxSTAT.
For the particular device, do a search for SPI2STATbits in all included header files.
It's in p24FJ128GA010.h as
#define SPI2STAT SPI2STAT extern volatile uint16_t SPI2STAT __attribute__((__sfr__)); __extension__ typedef struct tagSPI2STATBITS {...

Directly assigning to a std::vector after reserving does not throw error but does not increase vector size

Let's create a helper class to assist visualizing the issue:
class C
{
int ID = 0;
public:
C(const int newID)
{
ID = newID;
}
int getID()
{
return ID;
}
};
Suppose you create an empty std::vector<C> and then reserve it to hold 10 elements:
std::vector<C> pack;
pack.reserve(10);
printf("pack has %i\n", pack.size()); //will print '0'
Now, you assign a new instance of C into index 4 of the vector:
pack[4] = C(57);
printf("%i\n", pack[4].getID()); //will print '57'
printf("pack has %i\n", pack.size()); //will still print '0'
I found two things to be weird here:
1) shouldn't the assignment make the compiler (Visual Studio 2015, Release Mode) throw an error even in Release mode?
2) since it does not and the element is in fact stored in position 4, shouldn't the vector then have size = 1 instead of zero?
Undefined behavior is still undefined. If we make this a vector of objects, you would see the unexpected behavior more clearly.
#include <iostream>
#include <vector>
struct Foo {
int data_ = 3;
};
int main() {
std::vector<Foo> foos;
foos.reserve(10);
std::cout << foos[4].data_; // This probably doesn't output 3.
}
Here, we can see that because we haven't actually allocated the object yet, the constructor hasn't run.
Another example, since you're using space that the vector hasn't actually started allocating to you, if the vector needed to reallocate it's backing memory, the value that you wrote wouldn't be copied.
#include <iostream>
#include <vector>
int main() {
std::vector<int> foos;
foos.reserve(10);
foos[4] = 100;
foos.reserve(10000000);
std::cout << foos[4]; // Probably doesn't print 100.
}
Short answers:
1) There is no reason to throw an exception since operator[] is not supposed to verify the position you have passed. It might do so in Debug mode, but for sure not in Release (otherwise performance would suffer). In Release mode compiler trusts you that code you provide is error-proof and does everything to make your code fast.
Returns a reference to the element at specified location pos. No
bounds checking is performed.
http://en.cppreference.com/w/cpp/container/vector/operator_at
2) You simply accessed memory you don't own yet (reserve is not resize), anything you do on it is undefined behavior. But, you have never added an element into vector and it has no idea you even modified its buffer. And as #Bill have shown, the vector is allowed to change its buffer without copying your local change.
EDIT:
Also, you can get exception due to boundary checking if you use vector::at function.
That is: pack.at(4) = C(57); throws exception
Example:
https://ideone.com/sXnPzT

How do I declare a user defined function in OMNet++?

I have declared a function in the c++ file as stated in the documentation and called it in the .ned file. But it gives the following error.
error:expected constructor, destructor, or type conversion before ‘(’ token Define_Function(dijkstra, 1);
The following is my c++ file.
#include <omnetpp.h>
#include "stdio.h"
#include "Node.h"
#include "cdelaychannel.h"
Define_Function(dijkstra, 1);
double dijkstra(double start = 1){
....
....
}
In my network description file, I've called the function.
package myproject;
#license(LGPL);
dijkstra(1.0);
Why is it giving me the error?
If you want to create a function for using it in NED files, you have to do it as described in OMNeT++ Manual. An example could be the following:
static cNEDValue ned_foo(cComponent *context, cNEDValue argv[], int argc)
int a = (long) argv[0];
int b = (long) argv[1];
return a*b;
}
Define_NED_Function(ned_foo,"int ned_foo(int a, int b)");

Using an old device file for char device driver

I have two questions as I'm trying device drivers as a beginner.
I created one module , loaded it, it dynamically took major number 251 say. Number of minor devices is kept 1 only i.e minor number 0. For testing , I tried echo and cat on the device file (created using mknod) and it works as expected. Now if I unload the module but don't remove /dev entry and again load the module with same major number and try writing/reading to same device file which was used previously, kernel crashes. I know we shouldn't do this but just want to understand what happens in this scenario which causes this crash. I think something that VFS does.
When I do cat on device file, the read keeps on happening indefinitely. why? To stop that needed to use offset manipulation. This looks to be because buffer length is coming as 32768 as default to read?
EDIT: further in this I added one ioctl function as below, then I'm getting error regarding the storage class of init and cleanup function, which work well if no ioctl is defined. Not getting the link between ioctl and the init/cleanup functions' storage class. Updated code is posted. Errors are below:
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:95:12: error: invalid storage class for function ‘flow_init’
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c: In function ‘flow_init’:
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:98:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c: In function ‘flow_ioctl’:
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:112:13: error: invalid storage class for function ‘flow_terminate’
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:119:1: error: invalid storage class for function ‘__inittest’
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:119:1: warning: ‘alias’ attribute ignored [-Wattributes]
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:120:1: error: invalid storage class for function ‘__exittest’
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:120:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:120:1: warning: ‘alias’ attribute ignored [-Wattributes]
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:120:1: error: expected declaration or statement at end of input
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c: At top level:
/home/diwakar/Documents/my_modules/first_test_module/flowTest.c:73:13: warning: ‘flow_ioctl’ defined but not used [-Wunused-function]
Below is the code:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#define SUCCESS 0
#define BUF_LEN 80
#define FLOWTEST_MAGIC 'f'
#define FLOW_QUERY _IOR(FLOWTEST_MAGIC,1,int)
MODULE_LICENSE("GPL");
int minor_num=0,i;
int num_devices=1;
int fopen=0,counter=0,ioctl_test;
static struct cdev ms_flow_cd;
static char c;
///// Open , close and rest of the things
static int flow_open(struct inode *f_inode, struct file *f_file)
{
printk(KERN_ALERT "flowtest device: OPEN\n");
return SUCCESS;
}
static ssize_t flow_read(struct file *f_file, char __user *buf, size_t
len, loff_t *off)
{
printk(KERN_INFO "flowtest Driver: READ()\nlength len=%d, Offset = %d\n",len,*off);
/* Check to avoid the infinitely printing on screen. Return 1 on first read, and 0 on subsequent read */
if(*off==1)
return 0;
printk(KERN_INFO "Copying...\n");
copy_to_user(buf,&c,1);
printk(KERN_INFO "Copied : %s\n",buf);
*off = *off+1;
return 1; // Return 1 on first read
}
static ssize_t flow_write(struct file *f_file, const char __user *buf,
size_t len, loff_t *off)
{
printk(KERN_INFO "flowtest Driver: WRITE()\n");
if (copy_from_user(&c,buf+len-2,1) != 0)
return -EFAULT;
else
{
printk(KERN_INFO "Length len = %d\n\nLast character written is - %c\n",len,*(buf+len-2));
return len;
}
}
static int flow_close(struct inode *i, struct file *f)
{
printk(KERN_INFO "ms_tty Device: CLOSE()\n");
return 0;
}
///* ioctl commands *///
static long flow_ioctl (struct file *filp,unsigned int cmd, unsigned long arg)
{
switch(cmd) {
case FLOW_QUERY:
ioctl_test=51;
return ioctl_test;
default:
return -ENOTTY;
}
///////////////////File operations structure below/////////////////////////
struct file_operations flow_fops = {
.owner = THIS_MODULE,
.llseek = NULL,
.read = flow_read,
.write = flow_write,
.unlocked_ioctl = flow_ioctl,
.open = flow_open,
.release = flow_close
};
static int flow_init(void)
{
printk(KERN_ALERT "Here with flowTest module ... loading...\n");
int result=0;
dev_t dev=0;
result = alloc_chrdev_region(&dev, minor_num,
num_devices,"mod_flowtest"); // allocate major number dynamically.
i=MAJOR(dev);
printk(KERN_ALERT "Major allocated = %d",i);
cdev_init(&ms_flow_cd,&flow_fops);
cdev_add(&ms_flow_cd,dev,1);
return 0;
}
static void flow_terminate(void)
{
dev_t devno=MKDEV(i,0); // wrap major/minor numbers in a dev_t structure , to pass for deassigning.
printk(KERN_ALERT "Going out... exiting...\n");
unregister_chrdev_region(devno,num_devices); //remove entry from the /proc/devices
}
module_init(flow_init);
module_exit(flow_terminate);
1- You're missing cdev_del() in your cleanup function. Which means the device stays registered, but the functions to handle it are unloaded, thus the crash. Also, cdev_add probably fails on the next load, but you don't know because you're not checking return values.
2- It looks ok... you modify offset, return the correct number of bytes, and then return 0 if offset is 1, which indicates EOF. But you should really check for *off >= 1.
EDIT-
The length passed into your read handler function comes all the way from user-land read(). If the user opens the device file and calls read(fd, buf, 32768);, that just means the user wants to read up to 32768 bytes of data. That length gets passed all the way to your read handler. If you don't have 32768 bytes of data to supply, you supply what you have, and return the length. Now, the user code isn't sure if that's the end of the file or not, so it tries for another 32768 read. You really have no data now, so you return 0, which tells the user code that it has hit EOF, so it stops.
In summary, what you're seeing as some sort of default value at the read handler is just the block size that the utility cat uses to read anything. If you want to see a different number show up at your read function, try using dd instead, since it lets you specify the block size.
dd if=/dev/flowtest of=/dev/null bs=512 count=1
In addition, this should read one block and stop, since you're specifying count=1. If you omit count=1, it will look more like cat, and try to read until EOF.
For 2, make sure you start your module as a char device when using mknod.
mknod /dev/you_device c major_number minor_number

Resources