Sending data to web using arduino GSM module using GPRS - web

#include <SoftwareSerial.h>
SoftwareSerial GSM(9, 10); // RX, TX
int sensor=5;
enum _parseState {
PS_DETECT_MSG_TYPE,
PS_IGNORING_COMMAND_ECHO,
PS_HTTPACTION_TYPE,
PS_HTTPACTION_RESULT,
PS_HTTPACTION_LENGTH,
PS_HTTPREAD_LENGTH,
PS_HTTPREAD_CONTENT
};
byte parseState = PS_DETECT_MSG_TYPE;
char buffer[80];
byte pos = 0;
int contentLength = 0;
void resetBuffer() {
memset(buffer, 0, sizeof(buffer));
pos = 0;
}
void sendGSM(const char* msg, int waitMs = 500) {
GSM.println(msg);
delay(waitMs);
while(GSM.available()) {
parseATText(GSM.read());
}
}
void setup()
{
GSM.begin(9600);
Serial.begin(9600);
sendGSM("AT+SAPBR=3,1,\"APN\",\"zongwap\"");
sendGSM("AT+SAPBR=1,1",300);
sendGSM("AT+HTTPINIT");
sendGSM("AT+HTTPPARA=\"CID\",1");
sendGSM("AT+HTTPPARA=\"URL\",\"http://afridiofkh.000webhostapp.com?
sensor1="" + sensor + ""\"""");
sendGSM("AT+HTTPACTION=0");
}
void loop()
{
while(GSM.available()) {
parseATText(GSM.read());
}
}
void parseATText(byte b) {
buffer[pos++] = b;
if ( pos >= sizeof(buffer) )
resetBuffer(); // just to be safe
/*
// Detailed debugging
Serial.println();
Serial.print("state = ");
Serial.println(state);
Serial.print("b = ");
Serial.println(b);
Serial.print("pos = ");
Serial.println(pos);
Serial.print("buffer = ");
Serial.println(buffer);*/
switch (parseState) {
case PS_DETECT_MSG_TYPE:
{
if ( b == '\n' )
resetBuffer();
else {
if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
parseState = PS_IGNORING_COMMAND_ECHO;
}
else if ( b == ':' ) {
//Serial.print("Checking message type: ");
//Serial.println(buffer);
if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
Serial.println("Received HTTPACTION");
parseState = PS_HTTPACTION_TYPE;
}
else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
Serial.println("Received HTTPREAD");
parseState = PS_HTTPREAD_LENGTH;
}
resetBuffer();
}
}
}
break;
case PS_IGNORING_COMMAND_ECHO:
{
if ( b == '\n' ) {
Serial.print("Ignoring echo: ");
Serial.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPACTION_TYPE:
{
if ( b == ',' ) {
Serial.print("HTTPACTION type is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_RESULT;
resetBuffer();
}
}
break;
case PS_HTTPACTION_RESULT:
{
if ( b == ',' ) {
Serial.print("HTTPACTION result is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_LENGTH;
resetBuffer();
}
}
break;
case PS_HTTPACTION_LENGTH:
{
if ( b == '\n' ) {
Serial.print("HTTPACTION length is ");
Serial.println(buffer);
// now request content
GSM.print("AT+HTTPREAD=0,");
GSM.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPREAD_LENGTH:
{
if ( b == '\n' ) {
contentLength = atoi(buffer);
Serial.print("HTTPREAD length is ");
Serial.println(contentLength);
Serial.print("HTTPREAD content: ");
parseState = PS_HTTPREAD_CONTENT;
resetBuffer();
}
}
break;
case PS_HTTPREAD_CONTENT:
{
// for this demo I'm just showing the content bytes in the serial monitor
Serial.write(b);
contentLength--;
if ( contentLength <= 0 ) {
// all content bytes have now been read
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
}
}
i even don't understand the code but i get the idea and when i am trying to post the data to web its not working i don't know what's wrong with it
i am getting web content back but i can't post data to the web
i tried both get and post method non of them brought luck to me

The http request you made in your code has some mistakes.You can't request from arduino as you did.
When using 000webhost for database the best way is to make use of PHP.You can upload PHP files by selecting File Manager and then select "Upload files now" .In that there is a folder named "public_html" ,it's where the PHP codes are to be uploaded.
Now here is what you want to do.You want to create a PHP code which would perform the insertion operation to the database when the URL of this php code is requested.Then you can request this link from arduino for performing insertion.
The PHP code is ( Please provide your username,password,dbname,table name,column name in the provided locations of the code and upload it as i said above) :
<?php
$servername = "localhost";
$username = "provide your username here";
$password = "password here";
$dbname = "database name here";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "INSERT INTO table_name (column_name) VALUES ('".mysqli_real_escape_string($conn,$_GET['sensor1'])."')";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?>
Obtain the URL of the uploaded PHP code (right click uploaded file and click view , then copy URL in the browser). You can use it in your Arduino sketch.
Your arduino code should look like ( URL in this sketch is incomplete replace it with one obtained as i said above [ http://afridiofkh.000webhostapp.com/phpfilename.php this is the one to be replaced.starting from http till ? mark is to be replaced] ) :
#include <SoftwareSerial.h>
SoftwareSerial GSM(9, 10); // RX, TX
int sensor=5;
enum _parseState {
PS_DETECT_MSG_TYPE,
PS_IGNORING_COMMAND_ECHO,
PS_HTTPACTION_TYPE,
PS_HTTPACTION_RESULT,
PS_HTTPACTION_LENGTH,
PS_HTTPREAD_LENGTH,
PS_HTTPREAD_CONTENT
};
byte parseState = PS_DETECT_MSG_TYPE;
char buffer[130],url[130]; //adjust as your url length
byte pos = 0;
int contentLength = 0;
void resetBuffer() {
memset(buffer, 0, sizeof(buffer));
pos = 0;
}
void sendGSM(const char* msg, int waitMs = 500) {
GSM.println(msg);
delay(waitMs);
while(GSM.available()) {
parseATText(GSM.read());
}
}
void setup()
{
GSM.begin(9600);
Serial.begin(9600);
sendGSM("AT+SAPBR=3,1,\"APN\",\"zongwap\"");
sendGSM("AT+SAPBR=1,1",300);
sendGSM("AT+HTTPINIT");
sendGSM("AT+HTTPPARA=\"CID\",1");
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://afridiofkh.000webhostapp.com/phpfilename.php?sensor1=%d\"",sensor);
sendGSM(url);
sendGSM("AT+HTTPACTION=0");
}
void loop()
{
while(GSM.available()) {
parseATText(GSM.read());
}
}
void parseATText(byte b) {
buffer[pos++] = b;
if ( pos >= sizeof(buffer) )
resetBuffer(); // just to be safe
/*
// Detailed debugging
Serial.println();
Serial.print("state = ");
Serial.println(state);
Serial.print("b = ");
Serial.println(b);
Serial.print("pos = ");
Serial.println(pos);
Serial.print("buffer = ");
Serial.println(buffer);*/
switch (parseState) {
case PS_DETECT_MSG_TYPE:
{
if ( b == '\n' )
resetBuffer();
else {
if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
parseState = PS_IGNORING_COMMAND_ECHO;
}
else if ( b == ':' ) {
//Serial.print("Checking message type: ");
//Serial.println(buffer);
if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
Serial.println("Received HTTPACTION");
parseState = PS_HTTPACTION_TYPE;
}
else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
Serial.println("Received HTTPREAD");
parseState = PS_HTTPREAD_LENGTH;
}
resetBuffer();
}
}
}
break;
case PS_IGNORING_COMMAND_ECHO:
{
if ( b == '\n' ) {
Serial.print("Ignoring echo: ");
Serial.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPACTION_TYPE:
{
if ( b == ',' ) {
Serial.print("HTTPACTION type is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_RESULT;
resetBuffer();
}
}
break;
case PS_HTTPACTION_RESULT:
{
if ( b == ',' ) {
Serial.print("HTTPACTION result is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_LENGTH;
resetBuffer();
}
}
break;
case PS_HTTPACTION_LENGTH:
{
if ( b == '\n' ) {
Serial.print("HTTPACTION length is ");
Serial.println(buffer);
// now request content
GSM.print("AT+HTTPREAD=0,");
GSM.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPREAD_LENGTH:
{
if ( b == '\n' ) {
contentLength = atoi(buffer);
Serial.print("HTTPREAD length is ");
Serial.println(contentLength);
Serial.print("HTTPREAD content: ");
parseState = PS_HTTPREAD_CONTENT;
resetBuffer();
}
}
break;
case PS_HTTPREAD_CONTENT:
{
// for this demo I'm just showing the content bytes in the serial monitor
Serial.write(b);
contentLength--;
if ( contentLength <= 0 ) {
// all content bytes have now been read
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
}
}
This would perform the insertion operation as you need to.PHP is easy as it can be used to extend the operations.

Related

Using RegisterHotKey with number pad values not working?

I have some constants:
constexpr int MonitorDisplay1 = 100;
constexpr int MonitorDisplay2 = 200;
constexpr int MonitorDisplay3 = 400;
constexpr int MonitorDisplay4 = 500;
constexpr int MonitorDisplay1KeyPad = 101;
constexpr int MonitorDisplay2KeyPad = 201;
constexpr int MonitorDisplay3KeyPad = 401;
constexpr int MonitorDisplay4KeyPad = 501;
I have an OnCreate where I setup the hot keys:
int CCenterCursorOnScreenDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1)
return -1;
auto RegisterAppHotkey = [hAppWnd = GetSafeHwnd()](const int nHotKeyID, UINT vk)->bool
{
if (!::RegisterHotKey(hAppWnd, nHotKeyID, MOD_CONTROL | MOD_SHIFT, vk))
{
auto const ec = ::GetLastError();
auto const err_msg = std::format(L"RegisterHotKey failed (error: {})\n",
ec);
AfxMessageBox(err_msg.c_str());
return false;
}
return true;
};
if (m_monitors.rcMonitors.size() > 0)
{
if (!RegisterAppHotkey(MonitorDisplay1, '1'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay1KeyPad, VK_NUMPAD1))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 1)
{
if (!RegisterAppHotkey(MonitorDisplay2, '2'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay2KeyPad, VK_NUMPAD2))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 2)
{
if (!RegisterAppHotkey(MonitorDisplay3, '3'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay3KeyPad, VK_NUMPAD3))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 3)
{
if (!RegisterAppHotkey(MonitorDisplay4, '4'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay4KeyPad, VK_NUMPAD4))
{
return -1;
}
}
return 0;
}
Previously I just had the 4 hotkeys for 1 / 2 / 3 and 4. They still work. I tried to add new hotkeys for for the number pad on the keyboard, but they are not working.
My OnHotKey handler:
void CCenterCursorOnScreenDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
if (nHotKeyId == MonitorDisplay1 || nHotKeyId == MonitorDisplay1KeyPad)
{
CenterCursorOnMonitor(0);
}
else if (nHotKeyId == MonitorDisplay2 || nHotKeyId == MonitorDisplay2KeyPad)
{
CenterCursorOnMonitor(1);
}
else if (nHotKeyId == MonitorDisplay3 || nHotKeyId == MonitorDisplay3KeyPad)
{
CenterCursorOnMonitor(2);
}
else if (nHotKeyId == MonitorDisplay4 || nHotKeyId == MonitorDisplay4KeyPad)
{
CenterCursorOnMonitor(3);
}
__super::OnHotKey(nHotKeyId, nKey1, nKey2);
}
But the number pad versions are not working. Why?
I am unregistering all 8 hotkeys, and num-lock is on. I get no warnings when registering.
This article explains List of Keys (Keyboard, Mouse and Joystick):
Because I was using CTRL + SHIFT, then the meaning of the 4 numeric keys was changing:
End
Down
Page Down
Left
It made sense to change my hotkeys to CTRL + ALT instead to avoid this issue.

Accelerometer data over BLE are not sent in synch

I am sending temperature, humidity, pressure and accelerometer data over BLE, from Arduino (peripheral) to Raspberry Pi 4 (central). I created BLE characteristic per each acceleration dimension (accX, accY, accZ), and I am subscribing to these characteristics.
However, I put counter for each characteristic and realized that data are not sent in order:
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] x = 233
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] y = 230
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] z = 236
So x is read 233 times while y 230 times vice versa. In ideal scenario, they all should be same.
I am posting my full Arduino code minus comments, hence I believe it might be needed:
#include <ArduinoBLE.h>
#include <Arduino_HTS221.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_LSM9DS1.h>
#define BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE "181A"
#define BLE_UUID_TEMPERATURE "2A6E"
#define BLE_UUID_HUMIDITY "2A6F"
#define BLE_UUID_PRESSURE "2A6D"
#define BLE_UUID_ACCELEROMETER_SERVICE "1101"
#define BLE_UUID_ACCELEROMETER_X "2101"
#define BLE_UUID_ACCELEROMETER_Y "2102"
#define BLE_UUID_ACCELEROMETER_Z "2103"
#define BLE_DEVICE_NAME "Hako"
#define BLE_LOCAL_NAME "Hako"
BLEService environmentalSensingService(BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE);
BLEService accelerometerService(BLE_UUID_ACCELEROMETER_SERVICE);
BLEShortCharacteristic temperatureCharacteristic(BLE_UUID_TEMPERATURE, BLERead | BLENotify);
BLEUnsignedShortCharacteristic humidityCharacteristic(BLE_UUID_HUMIDITY, BLERead | BLENotify);
BLEUnsignedLongCharacteristic pressureCharacteristic(BLE_UUID_PRESSURE, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_X(BLE_UUID_ACCELEROMETER_X, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_Y(BLE_UUID_ACCELEROMETER_Y, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_Z(BLE_UUID_ACCELEROMETER_Z, BLERead | BLENotify);
#define ENV_SENSOR_UPDATE_INTERVAL (1000)
#define ACC_SENSOR_UPDATE_INTERVAL (1000)
typedef struct __attribute__((packed))
{
float temperature;
float humidity;
float pressure;
bool updated = false;
} env_sensor_data_t;
env_sensor_data_t envSensorData;
typedef struct __attribute__((packed))
{
float accX;
float accY;
float accZ;
bool updated = false;
} acc_sensor_data_t;
acc_sensor_data_t accSensorData;
#define BLE_LED_PIN LED_BUILTIN
void setup()
{
Serial.begin(9600);
while (!Serial);
Serial.println( "BLE Example - Environmental Sensing Service (ESS)" );
pinMode( BLE_LED_PIN, OUTPUT );
digitalWrite( BLE_LED_PIN, LOW );
// Without Serial when using USB power bank HTS sensor seems to needs some time for setup
delay(10);
if (!HTS.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
if (!BARO.begin()) {
Serial.println( "Failed to initialize pressure sensor!" );
while (1);
}
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
if (!setupBleMode()) {
while (1);
}
else {
Serial.println( "BLE initialized. Waiting for clients to connect." );
}
}
void loop() {
bleTask();
if (envSensorTask()) {
envPrintTask();
}
if (accSensorTask()) {
accPrintTask();
}
}
bool envSensorTask() {
static long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis < ENV_SENSOR_UPDATE_INTERVAL) {
return false;
}
previousMillis = currentMillis;
envSensorData.temperature = HTS.readTemperature();
envSensorData.humidity = HTS.readHumidity();
envSensorData.pressure = BARO.readPressure() * 1000; // kPa -> Pa
envSensorData.updated = true;
return envSensorData.updated;
}
bool accSensorTask() {
static long previousMillis2 = 0;
unsigned long currentMillis2 = millis();
float x = 0.00, y = 0.00, z = 0.00;
if (currentMillis2 - previousMillis2 < ACC_SENSOR_UPDATE_INTERVAL) {
return false;
}
previousMillis2 = currentMillis2;
if(IMU.accelerationAvailable()){
IMU.readAcceleration(x, y, z);
accSensorData.accX = x;
accSensorData.accY = y;
accSensorData.accZ = z;
accSensorData.updated = true;
}
return accSensorData.updated;
}
bool setupBleMode() {
if (!BLE.begin()) {
return false;
}
BLE.setDeviceName(BLE_DEVICE_NAME);
BLE.setLocalName(BLE_LOCAL_NAME);
BLE.setAdvertisedService(environmentalSensingService);
BLE.setAdvertisedService(accelerometerService);
environmentalSensingService.addCharacteristic(temperatureCharacteristic);
environmentalSensingService.addCharacteristic(humidityCharacteristic);
environmentalSensingService.addCharacteristic(pressureCharacteristic);
accelerometerService.addCharacteristic(accelerometerCharacteristic_X);
accelerometerService.addCharacteristic(accelerometerCharacteristic_Y);
accelerometerService.addCharacteristic(accelerometerCharacteristic_Z);
BLE.addService(environmentalSensingService);
BLE.addService(accelerometerService);
temperatureCharacteristic.writeValue(0);
humidityCharacteristic.writeValue(0);
pressureCharacteristic.writeValue(0);
accelerometerCharacteristic_X.writeValue(0);
accelerometerCharacteristic_Y.writeValue(0);
accelerometerCharacteristic_Z.writeValue(0);
BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
BLE.advertise();
return true;
}
void bleTask()
{
const uint32_t BLE_UPDATE_INTERVAL = 10;
static uint32_t previousMillis = 0;
uint32_t currentMillis = millis();
if (currentMillis - previousMillis >= BLE_UPDATE_INTERVAL) {
previousMillis = currentMillis;
BLE.poll();
}
if (envSensorData.updated) {
// BLE defines Temperature UUID 2A6E Type sint16 ( see XML links )
// Unit is in degrees Celsius with a resolution of 0.01 degrees Celsius
int16_t temperature = round(envSensorData.temperature * 100.0);
temperatureCharacteristic.writeValue(temperature);
// BLE defines Humidity UUID 2A6F Type uint16
// Unit is in percent with a resolution of 0.01 percent
uint16_t humidity = round(envSensorData.humidity * 100.0);
humidityCharacteristic.writeValue(humidity);
// BLE defines Pressure UUID 2A6D Type uint32
// Unit is in Pascal with a resolution of 0.1 Pa
uint32_t pressure = round(envSensorData.pressure * 10.0);
pressureCharacteristic.writeValue(pressure);
envSensorData.updated = false;
}
if (accSensorData.updated) {
// BLE does not define accelerometer UUID
// Alls units is in G
int16_t accelerometer_X = round(accSensorData.accX * 100.0);
accelerometerCharacteristic_X.writeValue(accelerometer_X);
int16_t accelerometer_Y = round(accSensorData.accY * 100.0);
accelerometerCharacteristic_Y.writeValue(accelerometer_Y);
int16_t accelerometer_Z = round(accSensorData.accZ * 100.0);
accelerometerCharacteristic_Z.writeValue(accelerometer_Z);
envSensorData.updated = false;
}
}
void envPrintTask() {
Serial.print( "Temperature = " );
Serial.print( envSensorData.temperature );
Serial.println( " °C" );
Serial.print( "Humidity = " );
Serial.print( envSensorData.humidity );
Serial.println( " %" );
Serial.print( "Pressure = " );
Serial.print( envSensorData.pressure );
Serial.println( " Pa" );
Serial.print(temperatureCharacteristic.subscribed());
Serial.print(humidityCharacteristic.subscribed());
Serial.println(pressureCharacteristic.subscribed());
}
void accPrintTask() {
Serial.print("AccX = ");
Serial.print(accSensorData.accX);
Serial.println(" G");
Serial.print("AccY = ");
Serial.print(accSensorData.accY);
Serial.println(" G");
Serial.print("AccZ = ");
Serial.print( accSensorData.accZ );
Serial.println(" G");
Serial.print(accelerometerCharacteristic_X.subscribed());
Serial.print(accelerometerCharacteristic_Y.subscribed());
Serial.println(accelerometerCharacteristic_Z.subscribed());
}
void blePeripheralConnectHandler(BLEDevice central) {
digitalWrite(BLE_LED_PIN, HIGH);
Serial.print(F( "Connected to central: " ));
Serial.println(central.address());
}
void blePeripheralDisconnectHandler( BLEDevice central ) {
digitalWrite(BLE_LED_PIN, LOW);
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
I am reading the data on Pi via in Node.js environment via #abandonware/noble library.
I will only post the related part, where I subscribe to characteristics first, then I read the data. You can see the counters at the end.
for (const [key, character] of Object.entries(ALL.characteristics)) {
// Check the notify bit, if not set, set it. //
if (character.properties.includes("notify")) {
const descriptors = await character.discoverDescriptorsAsync().catch(e => send(e));
for (const [key, descriptor] of Object.entries(descriptors)) {
node.log(descriptor);
let descriptorData = await descriptor.readValueAsync().catch(e => send(e));
if (descriptorData[0] === bufferChecker[0] || descriptorData[1] === bufferChecker [1]) {
node.log(`The ${character.name} ${character.uuid} notify bit is disabled.`);
node.log("Enabling notification bit...");
descriptor.writeValueAsync(notifySetter).catch(e => send(e));
node.log (`Notification for ${character.name} characteristic is enabled.`);
} else {
node.log(`The ${character.name} ${character.uuid} notify bit is already enabled.`);
return;
}
}
} else {
node.log(`Notification is not allowed for ${character.name} characteristic.`)
}
}
for (const [key, character] of Object.entries(ALL.characteristics)) {
character.on('data', (data) => {
if (character.uuid === '2a6d') {
data = data.readUInt32LE() * decimalSetter[1];
environmentalData.payload[character.name] = data.toFixed(2);
counterPres++;
} else if (character.uuid === '2a6e') {
data = data.readUInt16LE() * decimalSetter[0];
environmentalData.payload[character.name] = data.toFixed(2);
counterTemp++;
} else if (character.uuid === '2a6f') {
data = data.readUInt16LE() * decimalSetter[0];
environmentalData.payload[character.name] = data.toFixed(2);
counterHum++;
} else if (character.uuid === '2101') {
data = data.readInt16LE() * decimalSetter[0];
accData.payload[character.name] = data.toFixed(2);
counterAccX++;
} else if (character.uuid === '2102') {
data = data.readInt16LE() * decimalSetter[0];
accData.payload[character.name] = data.toFixed(2);
counterAccY++;
} else if (character.uuid === '2103') {
data = data.readInt16LE() * decimalSetter[0];
accData.payload[character.name] = data.toFixed(2);
counterAccZ++;
}
node.log("x = " + counterAccX);
node.log("y = " + counterAccY);
node.log("z = " + counterAccZ);
// Sends Temp., Hum., and Pres. data together.
if ( (counterHum + counterPres + counterTemp) % 3 == 0 && (counterHum + counterPres + counterTemp) !== 0){
send(environmentalData);
}
});
// Character data event listener END //
}
I asked the same question at Arduino forum as well.
The peripherals GATT server only sends data if the measured value has really changed. This behaviour saves energy and bandwidth. I think your observation is therefore perfectly normal.

How to select multiple items in treewidget and delete those items?

When I am selecting items in treewidget and then clicked on delete button then is is just deleting top most item only from treewidget
Can you correct this code?
This function is calling in connect statement while clicking on button
void TableDockWidget::deleteGroup() {
QTreeWidgetItem *item = treeWidget->currentItem();
QTreeWidgetItem* nextItem = treeWidget->itemBelow(item);
if ( item == NULL ) return;
PeakGroup* group = getSelectedGroup(); //this function is using to //select items from treewidget
if ( group == NULL ) return;
PeakGroup* parentGroup = group->parent;
if ( parentGroup == NULL ) { //top level item
deleteGroup(group); //this is using to delete group
} else if ( parentGroup && parentGroup->childCount() ) { //this a child item
if ( parentGroup->deleteChild(group) ) {
QTreeWidgetItem* parentItem = item->parent();
if ( parentItem ) {
parentItem->removeChild(item);
delete(item);
}
}
}
//show NextItem
if(nextItem) treeWidget->setCurrentItem(nextItem,0);
return;
}
//here, code of function which is selecting items.
PeakGroup* TableDockWidget::getSelectedGroup() {
QTreeWidgetItem *item = treeWidget->currentItem();
if (!item) return NULL;
QVariant v = item->data(0,Qt::UserRole);
PeakGroup* group = v.value<PeakGroup*>();
if ( group != NULL ) { return group; }
return NULL;
}
// code of function which is deleting group
void TableDockWidget::deleteGroup(PeakGroup *groupX) {
qDebug() << "TableDockWidget::deleteGroup()";
if(!groupX) return;
int pos=-1;
for(int i=0; i < allgroups.size(); i++) {
if ( &allgroups[i] == groupX ) {
pos=i; break;
}
}
if (pos == -1) return;
//qDebug() << "Delete pos=" << pos;
QTreeWidgetItemIterator it(treeWidget);
while (*it) {
QTreeWidgetItem* item = (*it);
if (item->isHidden()) { ++it; continue; }
QVariant v = item->data(0,Qt::UserRole);
PeakGroup* group = v.value<PeakGroup*>();
if ( group != NULL and group == groupX) {
item->setHidden(true);
//Deleteing
allgroups.erase(allgroups.begin()+pos);
int posTree = treeWidget->indexOfTopLevelItem(item);
if (posTree != -1) treeWidget->takeTopLevelItem(posTree);
break;
}
++it;
}
for(unsigned int i = 0; i < allgroups.size(); i++) {
allgroups[i].groupId = i + 1;
}
updateTable();
_mainwindow->getEicWidget()->replotForced();
}
PeakGroup* TableDockWidget::getSelectedGroup() {
PeakGroup* group;
QList<QTreeWidgetItem*>selected = treeWidget->selectedItems();
if(selected.size() == 0) return NULL;
Q_FOREACH (QTreeWidgetItem* item, selected) {
QVariant v = item->data(0,Qt::UserRole);
group = v.value<PeakGroup*>();
item->setHidden(true);
}
if ( group != NULL ) { return group; }
else
return NULL;
}

I want to convert json according to my format

// I am converting sqlite data into json format
try
{
SQLiteDatabase db;
String dbDir= Environment.getExternalStorageDirectory()+"/"+getResources().getString(R.string.folderName);;
db=getActivity().openOrCreateDatabase(dbDir + "/" + getResources().getString(R.string.dbName), Context.MODE_PRIVATE, null);
Cursor c = db.rawQuery("select * from products", null);
Log.e("fetch_category", "" + c.getCount());
if (c.getCount() == 0)
{
}
else
{
c.moveToFirst();
JSONObject rowObject = new JSONObject();
do
{
int totalColumn = c.getColumnCount();
for( int i=0 ; i< totalColumn ; i++ )
{
if( c.getColumnName(i) != null )
{
try
{
if( c.getString(i) != null )
{
Log.d("TAG_NAME", c.getString(i) );
rowObject.put(c.getColumnName(i) , c.getString(i) );
}
else
{
rowObject.put( c.getColumnName(i) , "" );
}
}
catch( Exception e )
{
Log.d("TAG_NAME", e.getMessage() );
}
}
}
// billsModel=new Bills_model();
resultSet.put(rowObject);
Log.d("resultset",resultSet.toString());
}
while (c.moveToNext());
}
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
//out put is coming like this
[{"key","value"},{"key","value"}....]
//but i want to like this is it possible
{"product"[{"key","value"},{"key","value"}....]}
You can use Jackson library -
Create a response class.
Use #JsonProperty annotation -
#JsonProperty("product")
private String jsonArray;
//getter
//setter
Set your json response string in the response object.
//do following
JSONObject jobj=new JSONObject();
//and then put all array inside json object it will give desire result
jobj.put("products",resultSet.put(rowObject));

Compare two CString which contain Version no

In a code I have 2 CString which contain a part of version number,
First exe contain version 1.1234.3.1 and the second exe has version 1.2.3.1.
Code should be such that
Suppose
CString MinVreg,MinFref;
if(MinVreg<MinFref) //when MinVreg="1234" and MinFref="2"
{
//it enters in if loop.
//Update registry
}
elseif(MinVreg>MinFref)
{
//Show message box..
}
I think the operator check only first digit.So please tell me how to compare it as a number
You have to parse the strings to represent a version as an integer array, then perform a lexicographic compare.
bool ParseVersionString(unsigned digits[4], const CString& i_version)
{
return sscanf(i_version, "%d.%d.%d.%d", &digits[0], &digits[1],
&digits[2], &digits[3]) == 4;
}
int CompareVersions(unsigned ver1[4], unsigned ver2[4])
{
for (int i = 0; i != 4; ++i)
{
if (ver1[i] < ver2[i])
return -1;
if (ver1[i] > ver2[i])
return 1;
}
return 0;
}
Usage:
CString MinVreg("1.1234.3.1"), MinFref("1.2.3.1");
unsigned ver1[4], ver2[4];
if (ParseVersionString(ver1, MinVreg) &&
ParseVersionString(ver2, MinFref) &&
CompareVersions(ver1, ver2) < 0)
{
//Update registry
}
Try this:
if ( atoi((char*)(LPCTSTR)MinVreg) < atoi((char*)(LPCTSTR)MinFref)
{
//Do the Stuff
}
You should use strstr function to check if the character is present or not.
if( NULL != strstr(MinVreg, MinFref) )
{
//enter the loop
}
EDIT::
If you want to compare them as int, you need to convert them to int.
if( atoi(MinVreg) < atoi(MinFref) )
{
//MinVreg < MinFref, Do something
}
elseif( atoi(MinVreg) > atoi(MinFref) )
{
//MinVreg > MinFref, Do something
}
else
{
//MinVreg = MinFref, Do something
}
UPDATE:: After question data edited to MinVreg = 1.1234.3.1 and MinFref = 1.2.3.1
int a ;
a = strcmp( MinVreg, MinFref ) ;
if( a < 0 )
{
//MinVreg < MinFref, Do something
}
elseif( a > 0 )
{
//MinVreg > MinFref, Do something
}
else
{
//MinVreg = MinFref, Do something
}
Why use strings in the first place? Here's how I keep track of versions.
BOOL GetProductVersion(VS_FIXEDFILEINFO &fixedFileInfo, LPCTSTR szFileName)
{
DWORD dwHandle = 0;
DWORD dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
if (dwLen == 0)
return FALSE;
LPSTR lpVI = new CHAR[dwLen];
if (!lpVI)
return FALSE;
ZeroMemory(lpVI, dwLen);
GetFileVersionInfo(szFileName, dwHandle, dwLen, lpVI);
DWORD dwBufSize;
VS_FIXEDFILEINFO* lpFFI;
if (VerQueryValue(lpVI, "\\", (LPVOID*)&lpFFI, (PUINT)&dwBufSize))
{
fixedFileInfo = *lpFFI;
delete [] lpVI;
return TRUE;
}
delete [] lpVI;
return FALSE;
}
CString GetProductVersionAsString(LPCTSTR szFileName)
{
CString version;
VS_FIXEDFILEINFO ffi;
if (GetProductVersion(ffi, szFileName))
{
stringstream ss;
ss << HIWORD(ffi.dwProductVersionMS) << '.';
ss << LOWORD(ffi.dwProductVersionMS) << '.';
ss << HIWORD(ffi.dwProductVersionLS);
UINT beta = LOWORD(ffi.dwProductVersionLS);
if (beta)
ss << " beta" << beta;
version = ss.str().c_str();
}
return version;
}
DWORD GetProductVersionAsInteger(LPCTSTR szFileName)
{
DWORD version = 0;
VS_FIXEDFILEINFO ffi;
if (GetProductVersion(ffi, szFileName))
{
// Apply your number logic here!
// This code is suitable for x.y.z
version += 100 * HIWORD(ffi.dwProductVersionMS);
version += 10 * LOWORD(ffi.dwProductVersionMS);
version += HIWORD(ffi.dwProductVersionLS);
}
return version;
}
Hence, "1.0.2" becomes 102. Obviously, larger version numbers need other multipliers.

Resources