Reading Ettus E310 Barometer over I2C, always returns No Such Device or Address (-1) - i2c

I've been trying to write a I2C device driver for the BMP 180 barometer and temperature sensor found on the E310 (as seen in sheet 9 of the schematic.) I have been basing my code off of the example driver given by bosch.
The driver requires function pointers to block read and write, as well as a sleep, which are basically the only original code:
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
void user_delay_ms(uint32_t period)
The problem I am having is that this driver (as well as simpler SMBUS command only programs I have written) have always failed to read or write the i2c address 0x77, where the sensor should be located on the bus.
readBytes for device ID 0x77: -1 - No such device or address
Even though my code seems to work for locations that other devices are located at (though I haven't done more than ping them)
Motion Sensor:
readBytes for device ID 0x69: 0 - Success
Temperature Sensor:
readBytes for device ID 0x19: 0 - Success
I was wondering either what is wrong with my code that the device would be completely unresponsive, or what hardware configuration am I missing that would explain the lack of communication with the barometer at 0x77.
I notice that the BMP-180 barometer is placed on the auxiliary i2c of the Gyro MPU-9150, but the wiring and datasheet make me think it is in pass through mode and not master mode. Just a thought I had though.
Here is all of the code I have that interacts with the bmpDriver.
Compiled with the following
gcc test.c -o test -std=c11 -D _DEFAULT_SOURCE
#include "bmp280.c"
#include <linux/i2c-dev-user.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
int file;
file = open("/dev/i2c-0", O_RDWR);
if(file < 0)
{
printf("Failed to open /dev/i2c-0\n");
close(file);
return -1;
}
if(ioctl(file, I2C_SLAVE, dev_id) < 0)
{
printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
close(file);
return -2;
}
int readBytes;
readBytes = i2c_smbus_read_block_data(file, reg_addr, data);
printf("readBytes for device ID 0x%x: %d - %s\n", dev_id, readBytes, strerror(errno));
close(file);
return readBytes;
}
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
int file;
file = open("/dev/i2c-0", O_RDWR);
if(file < 0)
{
printf("Failed to open /dev/i2c-0\n");
close(file);
return -1;
}
if(ioctl(file, I2C_SLAVE, dev_id) < 0)
{
printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
close(file);
return -2;
}
int writeBytes;
uint8_t shortLen = len;
writeBytes = i2c_smbus_write_block_data(file, reg_addr, shortLen, data);
printf("writeBytes for device ID 0x%x: %d - %s\n", dev_id, writeBytes, strerror(errno));
close(file);
return writeBytes;
}
void user_delay_ms(uint32_t period){
unsigned int sleep = period;
usleep(sleep * 1000);
}
int main(){
int8_t rslt;
struct bmp280_dev user_bmp;
user_bmp.dev_id = BMP280_I2C_ADDR_SEC;
user_bmp.intf = BMP280_I2C_INTF;
user_bmp.read = user_i2c_read;
user_bmp.write = user_i2c_write;
user_bmp.delay_ms = user_delay_ms;
rslt = bmp280_init(&user_bmp);
if (rslt == BMP280_OK) {
printf("Device found with chip id 0x%x\n", user_bmp.chip_id);
}
else {
printf("Device not found, exiting...\n");
return -1;
}
struct bmp280_config conf;
rslt = bmp280_get_config(&conf, &user_bmp);
conf.filter = BMP280_FILTER_COEFF_2;
conf.os_pres = BMP280_OS_16X;
conf.os_temp = BMP280_OS_4X;
conf.odr = BMP280_ODR_1000_MS;
rslt = bmp280_set_config(&conf, &user_bmp);
rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &user_bmp);
struct bmp280_uncomp_data ucomp_data;
uint8_t meas_dur = bmp280_compute_meas_time(&user_bmp);
printf("Measurement duration: %dms\r\n", meas_dur);
uint8_t i;
for (i = 0; (i < 10) && (rslt == BMP280_OK); i++) {
printf("Running measurement: %d\n", i+1);
user_bmp.delay_ms(meas_dur);
rslt = bmp280_get_uncomp_data(&ucomp_data, &user_bmp);
int32_t temp32 = bmp280_comp_temp_32bit(ucomp_data.uncomp_temp, &user_bmp);
uint32_t pres32 = bmp280_comp_pres_32bit(ucomp_data.uncomp_press, &user_bmp);
uint32_t pres64 = bmp280_comp_pres_64bit(ucomp_data.uncomp_press, &user_bmp);
double temp = bmp280_comp_temp_double(ucomp_data.uncomp_temp, &user_bmp);
double pres = bmp280_comp_pres_double(ucomp_data.uncomp_press, &user_bmp);
printf("UT: %d, UP: %d, T32: %d, P32: %d, P64: %d, P64N: %d, T: %f, P: %f\r\n", \
ucomp_data.uncomp_temp, ucomp_data.uncomp_press, temp32, \
pres32, pres64, pres64 / 256, temp, pres);
user_bmp.delay_ms(1000);
}
if(rslt != BMP280_OK){
printf("Result not okay at measurement: %d\n", i);
}
}

Before starting off with a speculation I would make sure that the transmission is actually reaching the sensor behind the gyro. Just use any scope to measure SCL and SDA. If the device is getting the transmission, the scope reading will provide additional information on where the device NAKs.
One difference between the BMP and the other i2c devices you were able to address that gave me multiple headaches in the past:
the BMP seems to require a repeated start condition between device address and register read.
As far as I can remember, standard i2c libraries do not support this and you usually have to build your own read / write functions using linux/i2c-dev.h.

Related

esp32 rest chuncked response

Im trying to know the real wifi speed capabilities of the esp32, and so i created a simple routine using a common library
void speedTest(AsyncWebServerRequest *request)
{
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
}
but when i make the GET request, the board reset itself and in serial monitor i see the following log:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
E (17770) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (17770) task_wdt: - async_tcp (CPU 0/1)
E (17770) task_wdt: Tasks currently running:
E (17770) task_wdt: CPU 0: IDLE0
E (17770) task_wdt: CPU 1: loopTask
E (17770) task_wdt: Aborting.
abort() was called at PC 0x40131b44 on core 0
I also have tried to reduce the file size and the download goes fine, but for my purpose is useless.
Someone has already meet and solved this problem ? im not really a lambda lover, alternately a different library more customizable, if is possible I would not like to reimplement all the http protocol over socket.
thanks in adavance for the help.
comeplete code:
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
AsyncWebServer server(80);
const char* ssid = "testSpeed";
const char* psw = "12345678";
void notFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "Not found");
}
void speedTest(AsyncWebServerRequest *request)
{
#if 1
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
#endif
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, psw);
WiFi.softAPConfig(local_ip, gateway, subnet);
server.on("/stream", HTTP_GET, speedTest);
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
Looks like the implementation of AsyncWebServer is not meant for long-running transactions, as it never resets the task watchdog. As a workaround you can increase the watchdog timeout to its maximum limit of 60 s or disable it entirely. It's controlled by the following options in sdkconfig:
CONFIG_ESP_TASK_WDT=y # Task Watchdog is enabled
CONFIG_ESP_TASK_WDT_PANIC=y # Panic (reset) is invoked on timeout
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30 # Timeout in seconds
The normal way to change those is to run idf.py menuconfig (where they appear under "Component config", "Common ESP-related") but you can just update the file "sdkconfig" directly.
Undo those changes after you're finished with your experiments, it's usually a good idea to keep the Task Watchdog enabled.

How can we determine whether a socket is ready to read/write?

How can we determine whether a socket is ready to read/write in socket programming.
On Linux, use select() or poll().
On Windows, you can use WSAPoll() or select(), both from winsock2.
Mac OS X also has select() and poll().
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking. – https://linux.die.net/man/3/fd_set
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
poll() performs a similar task to select(2): it waits for one of a set of file descriptors to become ready to perform I/O.
– https://linux.die.net/man/2/poll
Example of select usage:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n");
exit(EXIT_SUCCESS);
}
Explanation of the above code:
FD_ZERO initializes the rfds set. FD_SET(0, &rfds) adds fd 0 (stdin) to the set. FD_ISSET can be used to check whether a specific file descriptor is ready after select returns.
The select call in this example waits until rfds has input or until 5 seconds passes. The two NULLs in the select call are where file descriptor sets (fd_sets) to be checked for ready to write status and exceptions, respectively, would be passed. The tv argument is the number of seconds and microseconds to wait. The first argument to select, nfds, is the highest numbered file descriptor in any of the three sets (read, write, exceptions sets) plus one.
Example of poll usage (from man7.org):
/* poll_input.c
Licensed under GNU General Public License v2 or later.
*/
#include <poll.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
int nfds, num_open_fds;
struct pollfd *pfds;
if (argc < 2) {
fprintf(stderr, "Usage: %s file...\n", argv[0]);
exit(EXIT_FAILURE);
}
num_open_fds = nfds = argc - 1;
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL)
errExit("malloc");
/* Open each file on command line, and add it 'pfds' array. */
for (int j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
if (pfds[j].fd == -1)
errExit("open");
printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);
pfds[j].events = POLLIN;
}
/* Keep calling poll() as long as at least one file descriptor is
open. */
while (num_open_fds > 0) {
int ready;
printf("About to poll()\n");
ready = poll(pfds, nfds, -1);
if (ready == -1)
errExit("poll");
printf("Ready: %d\n", ready);
/* Deal with array returned by poll(). */
for (int j = 0; j < nfds; j++) {
char buf[10];
if (pfds[j].revents != 0) {
printf(" fd=%d; events: %s%s%s\n", pfds[j].fd,
(pfds[j].revents & POLLIN) ? "POLLIN " : "",
(pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
(pfds[j].revents & POLLERR) ? "POLLERR " : "");
if (pfds[j].revents & POLLIN) {
ssize_t s = read(pfds[j].fd, buf, sizeof(buf));
if (s == -1)
errExit("read");
printf(" read %zd bytes: %.*s\n",
s, (int) s, buf);
} else { /* POLLERR | POLLHUP */
printf(" closing fd %d\n", pfds[j].fd);
if (close(pfds[j].fd) == -1)
errExit("close");
num_open_fds--;
}
}
}
}
printf("All file descriptors closed; bye\n");
exit(EXIT_SUCCESS);
}
Explanation of above code:
This code is a bit more complex than the previous example.
argc is the number of arguments. argv is the array of arguments given to the program. argc[0] is usually the name of the program. If argc is less than 2 (which means only one argument was given), the program outputs a usage message and exits with a failure code.
pfds = calloc(nfds, sizeof(struct pollfd)); allocates memory for an array of struct pollfd which is nfds elements long and zeroes the memory. Then there is a NULL check; if pfds is NULL, that means calloc failed (usually because the program ran out of memory), so the program prints the error with perror and exits.
The for loop opens each filename specified in argv and assigns it to corresponding elements of the pfd array. Then sets .events on each element to POLLIN to tell poll to check each file descriptor for whether it is ready to read
The while loop is where the actual call to poll() happens. The array of struct pollfds, pfds, the number of fds, nfds, and a timeout of -1 is passed to poll. Then the return value is checked for error (-1 is what poll return when there is an error) and if there is an error, the program prints an error message and exits. Then the number of ready file descriptors is printed.
In the second for loop inside the while loop, the program iterates over the array of pollfds and checks the .revents field of each structure. If that field is nonzero, an event occurred on the corresponding file descriptor. The program prints the file descriptor, and the event, which can be POLLIN (ready for input), POLLHUP (hang up), or POLLERR (error condition). If the event was POLLIN, the file is ready to be read.
The program then reads 10 bytes into buf. If an error happens when reading, the program prints an error and exits. Otherwise, the program prints the number of bytes read and the contents of the buffer buf.
In case of error or hang up (POLLERR, POLLHUP) the program closes the file descriptor and decrements num_open_fds.
Finally the program says that all file descriptors are closed and exits with EXIT_SUCCESS.

Why is pcap only capturing PTP messages in live capture mode?

I am using a Intel i210-T1 Network Interface Card.
I am running the avnu gptp client (https://github.com/Avnu/gptp) with:
sudo ./daemon_cl -S -V
The other side is a gPTP Master.
I want to live capture incoming UDP packets on an network interface with hardware timestamps.
I can see the UDP Packets with wireshark, so the packets are actually on the wire.
My problem is that pcap doesn't return any packets other than PTP (ethertype 0x88f7) at all.
Is this a bug or am i using pcap the wrong way?
I wrote a minimal example to show my problem.
The code prints:
enp1s0
returnvalue pcap_set_tstamp_type: 0
returnvalue pcap_set_tstamp_precision: 0
returnvalue pcap_activate: 0
and afterwards only:
packet received with ethertype:88f7
#include <iostream>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <pcap/pcap.h>
int main(int argc, char **argv)
{
char errbuf[PCAP_ERRBUF_SIZE];
std::string dev = "enp1s0";
pcap_t* pcap_dev;
int i = 0;
printf("%s\n", dev.c_str());
pcap_dev = pcap_create(dev.c_str(), errbuf);
if(pcap_dev == NULL)
{
printf("pcap_create(): %s\n", errbuf);
exit(1);
}
i = pcap_set_tstamp_type(pcap_dev, PCAP_TSTAMP_ADAPTER_UNSYNCED);
printf("returnvalue pcap_set_tstamp_type: %i\n", i);
i = pcap_set_tstamp_precision(pcap_dev, PCAP_TSTAMP_PRECISION_NANO);
printf("returnvalue pcap_set_tstamp_precision: %i\n", i);
i = pcap_activate(pcap_dev);
printf("returnvalue pcap_activate: %i\n", i);
struct pcap_pkthdr* pkthdr;
const u_char* bytes;
while (pcap_next_ex(pcap_dev, &pkthdr, &bytes))
{
struct ether_header* ethhdr = (struct ether_header*) bytes;
std::cout << "packet received with ethertype:" << std::hex << ntohs(ethhdr->ether_type) << std::endl;
}
}
The solution is to enable promiscuous mode by using function:
https://linux.die.net/man/3/pcap_set_promisc
promiscuous mode disables any filtering by lower layers so you get every message arriving on the interface.
int pcap_set_promisc(pcap_t *p, int promisc);
pcap_set_promisc() sets whether promiscuous mode should be set on a capture handle when the handle is activated. If promisc is non-zero, promiscuous mode will be set, otherwise it will not be set.
Return Value
pcap_set_promisc() returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.

Bluetooth connection refused

I am working on a Bluetooth project involving one Arduino (with Seeed bluetooth shield v2.0) and one ubuntu laptop. Basically, I want message exchanges between the Arduino and the laptop. I paired the Arduino bluetooth shield with the laptop. Then I use the code below (on the laptop) to test. The Arduino is set as a Slave. And the laptop sends a test message.
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv){
struct sockaddr_rc addr = {0};
int s, status;
char buf[1024] = {0};
char dest[18] = "00:0E:EA:CF:1E:62";
for (size_t i = 1; i <= 30; i++) {
addr.rc_channel = i;
str2ba(dest, &addr.rc_bdaddr);
// connect to server
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
if(status == 0) {
status = send(s, "Hello!", 6, 0);
status = recv(s, buf, sizeof(buf), 0);
if(status > 0)
printf("received %s\n", buf);
break;
}
}
if(status < 0)
perror("send error");
close(s);
return 0;
}
Below is the test code at Arduino side.
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 7
#define TxD 6
SoftwareSerial bt(RxD,TxD);
char buf[100];
size_t idx;
void setup() {
Serial.begin(9600);
bt.begin(9600);
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
setupBlueToothConnection();
}
void loop() {
Serial.println("Waiting ...");
idx = 0;
memset(buf, sizeof(buf), 0);
while(bt.available()){
buf[idx] = bt.read();
idx++;
}
while(idx >= 0){
bt.write(buf[idx]);
idx--;
}
delay(1000);
}
void setupBlueToothConnection() {
bt.print("AT");
delay(400);
bt.print("AT+DEFAULT"); // Restore all setup value to factory setup
delay(2000);
bt.print("AT+LADD?"); // Restore all setup value to factory setup
delay(2000);
bt.print("AT+NAMEProver"); // set the bluetooth name as "SeeedBTSlave"
delay(400);
bt.print("AT+PIN0000"); // set the pair code to connect
delay(400);
bt.print("AT+ROLE?");
delay(400);
bt.print("AT+AUTH0");
delay(400);
bt.flush();
}
I receive error message: "send error: Connection refused". What is the problem? Can some help me with this? Thanks!
Update: I guess it might be the problem with port number. But I checked the datasheet for Seeed Bluetooth shield v2.0 and has not found any clue regarding to setup port number.
Most common problem with Bluetooth on Arduino except for code is having Arduino connected to your PC over USB cable and trying to use Bluetooth, as far as I am aware most of the shields connect directly to hardware RX and TX of the Arduino board, which are the same ports used for USB communication to your PC.
So is your Arduino connected over a USB port to your PC?

streaming with tcp using opencv and socket

i have done simple tcp client/server program got working well with strings and character data...i wanted to take each frames(from a webcam) and sent it to server.. here is the part of client program where error happened:
line:66 if(send(sock, frame, sizeof(frame), 0)< 0)
error:
client.cpp:66:39: error: cannot convert ‘cv::Mat’ to ‘const void*’ for argument ‘2’ to ‘ssize_t send(int, const void*, size_t, int)
i cant recognise this error....kindly help...the following complete client program:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<netdb.h>
#include<unistd.h>
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[1024];
VideoCapture capture;
Mat frame;
capture.open( 1 );
if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
begin:
capture.read(frame);
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
goto end;
}
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket failed");
exit(1);
}
server.sin_family =AF_INET;
hp= gethostbyname(argv[1]);
if(hp == 0)
{
perror("get hostname failed");
close(sock);
exit(1);
}
memcpy(&server.sin_addr,hp->h_addr,hp->h_length);
server.sin_port = htons(5000);
if(connect(sock,(struct sockaddr *) &server, sizeof(server))<0)
{
perror("connect failed");
close(sock);
exit(1);
}
int c = waitKey(30);
if( (char)c == 27 ) { goto end; }
if(send(sock, frame, sizeof(frame), 0)< 0)
{
perror("send failed");
close(sock);
exit(1);
}
goto begin;
end:
printf("sent\n",);
close(sock);
return 0;
}
Because TCP provides a stream of bytes, before you can send something over a TCP socket, you must compose the exact bytes you want to send. Your use of sizeof is incorrect. The sizeof function tells you how many bytes are needed on your system to store the particular type. This bears no relationship to the number of bytes the data will require over the TCP connection which depends on the particular protocol layered on top of TCP you are implementing which must specify how data is to be sent at the byte level.
like david already said, you got the length wrong. sizeof() won't help, what you want is probably
frame.total() * frame.channels()
you can't send a Mat object, but you can send the pixels ( the data pointer ) , so this would be:
send(sock, frame.data,frame.total() * frame.channels(), 0)
but still a bad idea. sending uncompressed pixels over the netwotrk ? bahh.
please look at imencode/imdecode
i'm pretty sure, you got the client / server roles in reverse here.
usually the server holds the information to retrieve ( the webcam ), and the client connects to that
and requests an image.