How to insert for loop in void function? - c

is there possible to insert for loop in void function ?
void decode(unsigned char* msg)
{
int result[5];// can store our value
unsigned char lala[50];
if (strstr(msg, "UI01?") != msg) // write in Hyperterminal
{
sprintf(lala, "UI01 %d \r\n", result[0]); // UIO1 ADC Value
sendString(lala);
}
else if (strstr(msg, "UI02?") != msg) // write in Hyperterminal
{
sprintf(lala, "UI02 %d \r\n", result[1]); // UIO2 ADC Value
sendString(lala);
}
else if (strstr(msg, "UI03?") != msg) // write in Hyperterminal
{
sprintf(lala, "UI02 %d \r\n", result[2]); // UIO3 ADC Value
sendString(lala);
}
else if (strstr(msg, "UI04?") != msg) // write in Hyperterminal
{
sprintf(lala, "UI02 %d \r\n", result[3]); // UIO4 ADC Value
sendString(lala);
}
}
int main()
{
int result[5]; // can store four value
int a = 0; // start from UI0-UI4
while (1)
{
for (a = 0; a < 5; a++)
{
AD1CHS0bits.CH0SA = a; // UI0-UI4
AD1CHS0bits.CH0NA = 0; // Vreferences as channel 0 -ve input
AD1CON1bits.ADON = 1; // 1 = A/D Converter module is operating
AD1CON1bits.SAMP = 1; // sapling mode
__delay32(50); // delay after sampling
AD1CON1bits.SAMP = 0; //sampling bit
while (!AD1CON1bits.DONE);
result[a] = ADC1BUF0; // have 4 result
}
}
if (U1STAbits.URXDA == 1) //check if data avilbe
{
rxbuf [len] = U1RXREG;
if (rxbuf[len]== '\r')//press enter
{
sendChar (rxbuf[len]);
sendChar ('\n'); //new line
decode (rxbuf); // calling decode funtion
len = 0 ;
}
else
{
sendChar (rxbuf[len]);
len++;
}
}
}
from the code above, in void decode enable the code UIO1? is type in Hyperterminal, it will reply ADC value. Followed by UIO2? until UIO4? .
in the while(1) loop, the code is used to scan UIO1 until UIO4. Actually UIO1 until UIO4 have analog value to be read in digital value. I am using for loop, because it look more simple.
The problem is, in the void decode loop, I got error: subscripted value is neither array nor pointer . How to read the result value ?

result in main and result in decode are two different variables.
If you want decode to know about the result from main you should pass it as a parameter:
void decode(unsigned char* msg, int result[5])
{
// Remove declaration of result
// Keep the rest of the code
}
int main()
{
/* other code */
decode (rxbuf, result); // calling decode funtion
/* other code */
}

Related

Array Data Reading Failed

I am reading the data from a "Torque Wrench" using "USB Host Shield2.0" and Arduino UNO. I am receiving correct data from my "Torque Wrench" Data is receiving in a array.
But when I started reading data after "for" loop inside Void loop() I am receiving incorrect data. I attached Both output pictures correct and incorrect data.
Basically I am read data from Torque Wrench and send to receiver using Nrf24l01. I am receiving incorrect data.
My question is :- Why I am reading Incorrect data outside "for" loop.
Correct Data inside "for" loop :- enter image description here
Incorrect Data outside "for" loop :- enter image description here
#include <SPI.h> // for SPI communication
#include <nRF24L01.h>
#include <RF24.h>
#include <cdcacm.h>
#include <usbhub.h>
//#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {'R','x','A','A','A','B'}; // the address the the module
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
radio.stopListening();
#if !defined(__MIPSEL__)
while (!Serial);
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("USB Not Connected");
delay( 200 );
}
void loop() {
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
uint8_t data= Serial.read();
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
}
delay(10);
uint8_t buf[64];
uint16_t rcvd = 64;
char text[64];
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if ( rcvd ) {
for(uint16_t i=0; i < rcvd; i++ )
{
// Serial.print((char)buf[i]); // correct Data read from torque wrench
text[i] = (char)buf[i];
}
Serial.println(text); // reading wrong data here
//radio.write(&text, sizeof(text));
//Serial.println(text);
}
delay(10);
}
}
Character arrays must be null-terminated to count as C strings.
After the for loop, add text[rcvd] = '\0';
Also, your rcvd is fixed at 64. It needs to be one less than the array size for the null terminator to fit.

Want to publish array of 768 to publish to MQTT using Esp32 wrover module

I am trying to publish the array of 786 to the MQTT Topic using ESP32 Wrover module but at the MQTT box, I am only receiving an array of 249. I am using PubSubClient Library,
What I tried in the PubSubClient library MQTT_MAX_PACKET_SIZE increase size 512 bytes still receiving the same bytes of 249 on MQTT protocol.
Code:
//#include <ArduinoJson.h>
#include <WiFi.h>
//#include <PubSubClient.h>
#include <Wire.h>
#include "MLX90640_API.h"
#include "MLX90640_I2C_Driver.h"
//#ifndef MQTT_MAX_PACKET_SIZE
////#define MQTT_MAX_PACKET_SIZE 256
//#define MQTT_MAX_PACKET_SIZE 1000
//#endif
#define MQTT_MAX_PACKET_SIZE 1000
const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640
#define TA_SHIFT 8 //Default shift for MLX90640 in open air
float mlx90640To[768];
//char mlx90640To[768];
paramsMLX90640 mlx90640;
// Replace the next variables with your SSID/Password combination
//const char* ssid = "TP-Link_63DD";
//const char* password = "123456";
//
//const char* mqtt_server = "broker.emqx.io";
const char* ssid = "TP-Link_63DD";
const char* password = "123456";
const char* mqttServer = "broker.emqx.io";
//const char* mqttServer =" mqtt.dioty.co";
const int mqttPort = 1883;
const char* mqttUser = "******";
const char* mqttPassword = "12345";
//const char* mqttServer ="broker.hivemq.com";
//const int mqttPort = 1883;
//const char* mqttUser = "***********";
//const char* mqttPassword = "12345";
const byte led_gpio = 27;
#define row 24
#define clom 32
#define pixel 768
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[765];
int value = 0;
#define cap 800
//int lastMsg = 0;
//int value = 0;
void setup()
{
Wire.begin();
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
Serial.begin(115200); //Fast serial as possible
// setup_wifi();
// client.setServer(mqtt_server, 1883);
// client.setCallback(callback);
pinMode(led_gpio, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
while (!Serial); //Wait for user to open terminal
//Serial.println("MLX90640 IR Array Example");
if (isConnected() == false)
{
Serial.println("MLX90640 not detected at default I2C address. Please check wiring. Freezing.");
while (1);
}
Serial.println("MLX90640 online!");
//Get device parameters - We only have to do this once
int status;
uint16_t eeMLX90640[832];
status = MLX90640_DumpEE(MLX90640_address, eeMLX90640);
if (status != 0)
Serial.println("Failed to load system parameters");
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
if (status != 0)
Serial.println("Parameter extraction failed");
//Once params are extracted, we can release eeMLX90640 array
//MLX90640_SetRefreshRate(MLX90640_address, 0x02); //Set rate to 2Hz
MLX90640_SetRefreshRate(MLX90640_address, 0x03); //Set rate to 4Hz
//MLX90640_SetRefreshRate(MLX90640_address, 0x07); //Set rate to 64Hz
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
//delay(1000);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("\n Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Subscribe
client.subscribe("esp32/output");
// client.subscribe("esp32/temperature");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// StaticJsonBuffer<200> JSONbuffer;
void loop()
{
int boardArray [pixel];
int boardArrayTwo [row][clom];
client.loop();
//char mlx90640To[768];
// long startTime = millis();
for (byte x = 0 ; x < 2 ; x++)
{
uint16_t mlx90640Frame[834];
int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);
float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640);
float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640);
float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
float emissivity = 0.95;
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
//Serial.print("vdd= "); Serial.print(vdd);Serial.println("\n"); // used to print vdd
// Serial.print("Ta= "); Serial.print(Ta);Serial.println("\n"); // used to print Ta
// Serial.print("tr= "); Serial.print(tr);Serial.println("\n"); // used to print tr
//
Serial.println(" ");
}
//long stopTime = millis();
//
// StaticJsonBuffer<5000> JSONbuffer;
/*******************DynamicJsonDocument*****************************/
DynamicJsonDocument doc(13000);
//JsonObject& JSONencoder = JSONbuffer.createObject();
// JSONencoder["device"] = "ESP32";
// JSONencoder["sensorType"] = "T-Scanner";
// JsonArray& values = JSONencoder.createNestedArray("v");
doc["device"] = "ESP32";
doc["sensorType"] = "T-Scanner";
char arr[786];
for (int x = 0 ; x < 768 ; x++) //768 384
{
//if(x % 8 == 0) Serial.println();
Serial.print(mlx90640To[x],0); //value from sensor print on com port
// boardArray[x] = mlx90640To[x];
// values.add((uint8_t)mlx90640To[x]);
// array.add((uint8_t)mlx90640To[x]);
doc["values"][x] = (uint8_t)mlx90640To[x]; // AARAY value of 786 is store in values
Serial.print(",");
//delay(1000);
}
/* for (int x = 0; x < row; ++x)
{
for (int k = 0; k < clom; ++k){
boardArrayTwo[x][k] = boardArray[clom*x + k];
// tempData=boardArrayTwo[x][k];
// values.add(boardArrayTwo[x][k]);
// printf("%d ", boardArrayTwo[x][k]);
//n=sprintf(reply_buff," number %d ",tempData);
} } */
digitalWrite(led_gpio, HIGH);
//serializeJson(doc, Serial);
// JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
Serial.println("\nSending message to MQTT topic..");
// Serial.println(JSONmessageBuffer);
char JSONmessageBuffer[cap]; // JSON MESSAGE CHAR BUFFER
Serial.println(serializeJson(doc, Serial));
size_t n = serializeJson(doc, JSONmessageBuffer); // formation of serialization of data
size_t sizeq = sizeof(JSONmessageBuffer) / sizeof(JSONmessageBuffer[0]);
Serial.println(" JSONmessageBuffer_size");
Serial.println(sizeq);
// delay(1000);
// snprintf(JSONmessageBuffer,768,"%d",serializeJson(doc, Serial));
//snprintf(JSONmessageBuffer,768,"%ld",serializeJson(doc, Serial));
Serial.println("\nJSONmessageBuffer:::");
Serial.println(JSONmessageBuffer);
//Serial.println("\nJSONmessageBuffer_size");
//Serial.println(n);
//*************************Data send to PUBLISH TO MQTT TOPIC******************************/
//if (client.publish("ev8051/esp32/temperature",JSONmessageBuffer) == true) // sending JSONmessageBuffer data to topic "ev8051/esp32/temperature"
// boolean beginPublish(const char* topic, unsigned int plength, boolean retained);
// boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
if(client.publish("ev8051/esp32/temperature",JSONmessageBuffer,n) == true)
{
Serial.println("\nSuccess sending message");
} else {
Serial.println("\nError sending message");
}
client.endPublish();
if (!client.connected()) {
reconnect();
}
client.loop();
Serial.println("-------------");
//delay(1000);
delay(1000);
}
//Returns true if the MLX90640 is detected on the I2C bus
boolean isConnected()
{
Wire.beginTransmission((uint8_t)MLX90640_address);
if (Wire.endTransmission() != 0)
return (false); //Sensor did not ACK
return (true);
}
Please help...
Thanks in advance.

Working with byte array I get an "invalid conversion from char* to byte"

I am reading and writing to an RFID tag using MFRC522.h
I can currently read the UID of a card and dump it to "UIDChar"
The UID of a card typically is 8 characters.
UID Example: 467EE9A9
I can use the mfrc522.MIFARE_SetUid function to write this UID to a new card. In order to do this I have to set the newUID to:
0x46,0x7E,0xE9,0xA9f
I have written this into my code.
What I am wanting to do is convert the UID string into a byte array so that I can use that in place of my manually written 0x46,0x7E,0xE9,0xA9.
I use the convert function to convert the UID into that format.
It can that be displayed with "buf".
Serial.println(buf);
Now my problem. If I replace the
byte newUid[] = {0x46,0x7E,0xE9,0xA9f};
with
byte newUid[] = {buf};
I get the error
invalid conversion from 'char*' to 'byte {aka unsigned char}'
How can I set my "newUid" as "buf"?
#define SS_PIN 0 //D2
#define RST_PIN 2 //D1
#include <SPI.h>
#include <MFRC522.h>
/* For RFID */
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
char buf[40]; // For string to byte array convertor
void convert(char *s)
{
int i, j, k;
buf[0] = 0x0;
for (j = 0, i = 0, k = 0; j < strlen(s); j++)
{
if (i++ == 0) {
buf[k++] = '0';
buf[k++] = 'x';
}
buf[k++] = s[j];
if (i == 2) {
if(j != strlen(s) -1) buf[k++] = ',';
i = 0;
}
}
buf[k] = 0x0;
}
void clone() {
/* RFID Read */
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
//Show UID on serial monitor
Serial.println();
Serial.print(" UID tag :");
// Very basic UID dump
unsigned int hex_num;
hex_num = mfrc522.uid.uidByte[0] << 24;
hex_num += mfrc522.uid.uidByte[1] << 16;
hex_num += mfrc522.uid.uidByte[2] << 8;
hex_num += mfrc522.uid.uidByte[3];
// Get UID
int NFC_id = (int)hex_num;
Serial.print(NFC_id, HEX);
// Convert UID to string using an int and a base (hexadecimal)
String stringUID = String(NFC_id, HEX);
char UIDChar[10];
stringUID.toCharArray(UIDChar,10);
delay(1000);
Serial.println();
// Convert to uppercase
for (int i = 0; i < strlen(UIDChar); i++ )
{
if ( UIDChar[i] == NULL ) break;
UIDChar[i] = toupper(UIDChar[i]);
}
//Serial.print( &UIDChar[0] );
Serial.println();
convert(UIDChar);
Serial.println(buf);
/* RFID Write */
// Set new UID
// Change your UID hex string to 4 byte array
// I get error if I use byte newUid[] = {buf};
/* ERROR HERE */
byte newUid[] = {0x46,0x7E,0xE9,0xA9};
if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
Serial.println( "Wrote new UID to card." );
}
// Halt PICC and re-select it so DumpToSerial doesn't get confused
mfrc522.PICC_HaltA();
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
return;
}
// Dump the new memory contents
Serial.println( "New UID and contents:" );
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
void setup() {
Serial.begin ( 115200 );
/* RFID */
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522
clone();
}
void loop() {
}
When you write
byte newUid[] = {buf};
you are trying to initialise newUid with a single element (there's only one item inside your {}), and that element is buf, which is a char* (or a char[]). That's why you get the error - you are trying to assign an array with one char* to a variable whose elements are bytes.
Without reading your full code in detail, I don't know why you are trying to do this assignment, rather than just use your buf array as it is. But to fix the problem, you probably just want to use
byte* newUid = buf;

How to continually print output inside a switch statement?

I have been trying to continually print the PWM output of pin 3 inside the switch statement condition but it only prints once. Can I continually print it in serial monitor until it meets the second conditon? or use a while loop? or a if else ?
Here is my code I also have a code with a similar function but it uses if else but still it only prints once
void loop() {
// if there's any serial available, read it:
while (Serial.available() > 0) {
int InitVal = Serial.parseInt();
int red = Serial.parseInt();
switch(InitVal) {
case 1:
if (Serial.read() == '\n') {
analogWrite(redPin, red);
Serial.println(red);
Serial.write(red);
}
break;
case 0:
analogWrite(redPin, 0);
Serial.println(0);
Serial.write(0);
break;
}
}
}
I'am planning to inter-phase this with a GUI . A GUI sends ascii to the arduino reads it then sends the output value to the GUI.
Example
1.GUI sends [1,123] : 1 = the trigger point for the switch statement ; 123 = PWM value.
Arduino receives instructions and it prints out the pwm value
GUI receives pwm value and displays it
Revised code: Stuck at the last while loop maybe i could use a threading function in arduino so that the last while loop would be satisfied/dissatisfied?
void loop() {
int InitVal = 0;
// if there's any serial available, read it:
while (Serial.available() > 0) {
int InitVal = Serial.parseInt();
int red = Serial.parseInt();
switch(InitVal) {
case 1:
if (Serial.read() == '\n') {
InitVal = 1;
//analogWrite(redPin, red);
//Serial.println(red);
// Serial.write(red);
}
break;
case 0:
InitVal = 0;
//analogWrite(redPin, 0);
//Serial.println(0);
//Serial.write(0);
break;
}
if (InitVal) /* when enabled, blink leds */ {
delay(20);
while (InitVal == 1) /* loop forever */{
Serial.println(red);
Serial.write(red);
delay(20);
}
}
}
}
I discarded Serial.parseInt() function, removed the switch statments and followed #Arno Bozo advise on serial listening while following this tutorial on http://forum.arduino.cc/index.php?topic=396450.0
I came up with what I want and here is the code
const int redPin = 3;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
boolean newData = false;
int InitVal = 0; // change to init value or red
int red = 0;
void setup() {
// initialize serial:
Serial.begin(9600);
// make the pins outputs:
pinMode(redPin, OUTPUT);
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
One();
newData = false;
}
else {
Zero();
}
}
///////////////////// ///////////////////// /////////////////////
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
///////////////////// ///////////////////// /////////////////////
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
InitVal = atoi(strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
red = atoi(strtokIndx); // convert this part to an integer
}
///////////////////// ///////////////////// /////////////////////
void One() {
if (InitVal == 0){
delay(20);
Serial.println(0);
delay(20);
}
}
///////////////////// ///////////////////// /////////////////////
void Zero() {
if (InitVal == 1){
delay(20);
Serial.println(red);
delay(20);
}
}
In Summary the code works like this
1.In serial monitor send this <1,123> : 1 = the trigger point for the switch statement ; 123 = PWM value.
Arduino receives instructions and it prints out the pwm value
If you send <0,123> it prints a zero once
I post a refined code here. The architecture may be reused for serial treatment. I have written it as an example for people I meet and who are learning with arduino.
I have made comments and explanation of ways to avoid delay. Here it is used to print current value of pwm every 1s, without stopping with a delay(1000).
#include <Arduino.h>
// with schedule(f,i) , the function f() will be called every i ms
// schedule(f,i) lines are put in loop() function
// f is of type void f(void)
#define schedule(f,i) {static unsigned long l=0;unsigned long c=millis();if((unsigned long)(c-l)>=i){l=c;f();}}
const int ledPin = 13;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
boolean newCommandHasArrived=false, newParsedCommand=false;
String personalSerialBuffer=""; // char[] would be better; but String are so convenient
enum ECommand {ecmdNoPwm=0, ecmdPwm=1, ecmdBad=10 };
ECommand cmd=ecmdNoPwm;
int cmdArg=0;
boolean readSerialBuffer(String &personalSerialBuffer);
boolean parseCommand(String &apersonalSerialBuffer, ECommand &acmd, int &acmdArg);
void executeCommand(ECommand acmd, int &acmdArg);
void printCurrentValue() {Serial.println(String("cval:") + cmdArg);}
void loop() {
// transfer serial buffer in personal buffer
newCommandHasArrived = readSerialBuffer(personalSerialBuffer);
if (newCommandHasArrived) {
newCommandHasArrived = false;
newParsedCommand = parseCommand(personalSerialBuffer, cmd, cmdArg);
}
if (newParsedCommand) {
newParsedCommand = false;
executeCommand(cmd, cmdArg);
}
// I print current value every 1000ms
//delay(1000); // you can often use delay without pb, but it is a bad usage
// Here I provide you with a quick way to execute a task every 1000ms
{
const unsigned long delayBetweenExecution=1000;
static unsigned long lastTime=0;
unsigned long current = millis();
// note that C++ says that overflow on unsigned is well defined
// it calculates modulo arithmetic
if ((unsigned long)(millis() - lastTime) >= delayBetweenExecution) {
lastTime = current;
Serial.println(String("cval:") + cmdArg);
}
}
// We can make it shorter thanks to a macro:
// but you have to define a void function(void) that uses only global variable
// because it has no argument :
// void printCurrentValue() {Serial.print(String("cval:") + cmdArg);}
//schedule(printCurrentValue, 1000);
}
boolean readSerialBuffer(String &personalSerialBuffer) {
if (Serial.available() > 0) {
personalSerialBuffer.concat(Serial.readString());
}
// the frame is considered finished, if it ends with \n
if (personalSerialBuffer.endsWith("\n"))
return true;
else
return false;
}
boolean parseCommand(String &apersonalSerialBuffer, ECommand &acmd, int &acmdArg) {
// format [ 1, 123]\n
// I omit [ then I read first int : 1
// Note: I cannot detect if no int is found because it will return 0 that is a valid cmd
int readCmd = apersonalSerialBuffer.substring(1).toInt();
// conversion readCmd to acmd
switch (readCmd) {
case 0:
acmd = ecmdNoPwm; break;
case 1:
acmd = ecmdPwm; break;
default:
Serial.println(String("new command unknown: ") +
apersonalSerialBuffer);
apersonalSerialBuffer = "";
return false;
}
// find beginning of 2nd part, separated by ','
int sepPos = apersonalSerialBuffer.indexOf(',');
// no ',' : indexOf returns -1
if (sepPos == -1) {
Serial.println(String("new command could not be parsed: ") +
apersonalSerialBuffer);
apersonalSerialBuffer = "";
return false;
}
// Note: I cannot detect if no int is found because it will return 0 that is a valid cmd
acmdArg = apersonalSerialBuffer.substring(sepPos+1).toInt();
// All is fine
// I have to reset buffer before leaving
apersonalSerialBuffer = "";
return true;
}
void executeCommand(ECommand acmd, int &acmdArg) {
switch(acmd) {
case ecmdNoPwm:
// I erase acmdArg
acmdArg = 0;
analogWrite(ledPin, acmdArg);
Serial.println("cmd no pwm");
break;
case ecmdPwm:
analogWrite(ledPin, acmdArg);
Serial.print("cmd pwm:"); Serial.println(acmdArg);
break;
default:
analogWrite(ledPin, 0);
Serial.println("Bad cmd");
}
}

Bluetooth communications with C

I want to write 2 programs with C , one work on Robot1, the other work on Robot2.
So I want the program to send a signal from Robot1 via Bluetooth to Robot2 and Robot2 handles and accepts this signal (message)and reply to Robot1.
how to code this?
please I need any kind of help.
API OF my Robots:
/* function for serial communication */
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}
void SerRead(unsigned char *data, unsigned char length,unsigned int timeout)
{
unsigned char i = 0;
unsigned int time = 0;
UCSRB = 0x10; // enable receiver
/* non blocking */
if (timeout != 0) {
while (i < length && time++ < timeout) {
if (UCSRA & 0x80) {
data[i++] = UDR;
time = 0;
}
}
if (time > timeout) data[0] = 'T';
}
/* blocking */
else {
while (i < length) {
if (UCSRA & 0x80)
data[i++] = UDR;
}
}
}
-------------------------------------------------------------------------------------------Bluetooth Model...code...
#include "asuro.h"
void Sekunden(unsigned int s) //Unterprogramm für Sekundenschleife (maximal 65s)
{
unsigned int t; // Definierung t als Vorzeichenloses int
for(t=0;t<s*1000;t++) // 1000*s durchlaufen
{
Sleep(72); // = 1ms
}
}
int main (void)
{
unsigned char daten[2], merker=0; //Speicher bereitstellen, merker für start/stop
Init();
UBRRL = 0x67; //4800bps # 8MHz
Marke: // Endlosschleife
SerRead(daten,1,0); // Daten einlesen
switch (daten[0]) //und verarbeiten
{
case 0x38: MotorDir(FWD,FWD); // Vorwärts
MotorSpeed(merker*120,merker*120);
SerWrite("Vor \r",22);
break;
case 0x36: MotorDir(FWD,FWD); // Links
MotorSpeed(merker*120,merker*170);
SerWrite("Links \r",22);
break;
case 0x37: MotorDir(RWD,RWD); // Rückwärts
MotorSpeed(merker*120,merker*120);
SerWrite("Zurueck \r",22);
break;
case 0x34: MotorDir(FWD,FWD); // Rechts
MotorSpeed(merker*170,merker*120);
SerWrite("Rechts \r",22);
break;
case 0x35: if(merker==1)
{
MotorDir(FREE,FREE);// Stop
MotorSpeed(0,0);
SerWrite("Stop \r",22);
merker=0;
break;
}
else
{
MotorDir(FWD,FWD);// Start
MotorSpeed(120,120);
SerWrite("Start \r",22);
merker=1;
break;
}
}
i want to run this programm on my Robot.
Robot 2 needs to call SerRead with, lets say, a pointer to an empty buffer (length one or so), length one and zero as timeout. Afterwards, let it call SerWrite with a pointer to your buffer and length one.
Robot 1 should first call SerWrite with one byte of data and then wait for the result of a call to SerRead.

Resources