Bash ping script with LCD error message errors - c

I am working in Debian and I am trying to write a script that will ping a host (192.168.10.30) every 10 seconds.
Whenever the ping is not successful, I want to have the message "VPN Lost" be displayed on my LCD screen. Once the ping is successful again the "VPN Lost" message will disappear from my LCD screen, and the screen will display "STS300".
The code below keeps giving me an error when I try to compile it, and I do not understand why. (The code compiles fine, but once I added in the code for the ping it won't compile). The code that is giving me trouble is between the lines lcd_command(LINE_3); and lcd_command(LINE_4);
I am fairly new to this...
The errors I am getting are...
lcdSignal.c: In function 'main': lcdSignal.c:190:10: error: expected
'(' before 'true'
lcdSignal.c:190:10: error: 'true' undeclared (first use in this
function)
lcdSignal.c:190:10: note: each undeclared identifier is reported only
once for each function it appears in
lcdSignal.c:191:3: error: 'ping' undeclared (first use in this
function)
lcdSignal.c:191:12: error: too many decimal points in number
lcdSignal.c:191:9: error: 'c1' undeclared (first use in this function)
lcdSignal.c:191:12: error: expected ';' before numeric constant
lcdSignal.c:192:3: error: expected 'while' before 'lcd_writechars'
lcdSignal.c:193:7: error: expected '(' before '[' token
lcdSignal.c:193:12: error: '$' undeclared (first use in this function)
lcdSignal.c:193:19: error: unknown type name 'then'
lcdSignal.c:194:18: error: expected declaration specifiers or '...'
before string constant
lcdSignal.c:195:3: error: 'fi' undeclared (first use in this function)
lcdSignal.c:196:9: error: expected ';' before numeric constant
If someone could help me, I would greatly appreciate it!!!
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include "evgpio.h"
#include "STSConfig.h" // This file is where the strings are modified
void lcd_init(void);
void lcd_wait(void);
void lcd_command(uint16_t);
void lcd_writechars(unsigned char *dat);
// These are microsecond delays
#define SETUP 1
#define PULSE 2
#define HOLD 1
#define LINE_1 0x80 // beginning position of LCD line 1
#define LINE_2 0xC0 // beginning position of LCD line 2
#define LINE_3 0x94 // beginning position of LCD line 3
#define LINE_4 0xD4 // beginning position of LCD line 4
#define LCD_D0 74
#define LCD_D1 75
#define LCD_D2 72
#define LCD_D3 73
#define LCD_D4 70
#define LCD_D5 71
#define LCD_D6 68
#define LCD_D7 69
#define LCD_EN 64
#define LCD_WR 65
#define LCD_RS 66
#define LCD_BIAS 67
void lcd_write(uint8_t out)
{
evsetdata(LCD_D0, out & (1 << 0));
evsetdata(LCD_D1, out & (1 << 1));
evsetdata(LCD_D2, out & (1 << 2));
evsetdata(LCD_D3, out & (1 << 3));
evsetdata(LCD_D4, out & (1 << 4));
evsetdata(LCD_D5, out & (1 << 5));
evsetdata(LCD_D6, out & (1 << 6));
evsetdata(LCD_D7, out & (1 << 7));
}
void lcd_ddr(uint8_t out)
{
evsetddr(LCD_D0, out & (1 << 0));
evsetddr(LCD_D1, out & (1 << 1));
evsetddr(LCD_D2, out & (1 << 2));
evsetddr(LCD_D3, out & (1 << 3));
evsetddr(LCD_D4, out & (1 << 4));
evsetddr(LCD_D5, out & (1 << 5));
evsetddr(LCD_D6, out & (1 << 6));
evsetddr(LCD_D7, out & (1 << 7));
}
uint8_t lcd_read()
{
uint8_t out = 0;
out |= (evgetin(LCD_D0) << 0);
out |= (evgetin(LCD_D1) << 1);
out |= (evgetin(LCD_D2) << 2);
out |= (evgetin(LCD_D3) << 3);
out |= (evgetin(LCD_D4) << 4);
out |= (evgetin(LCD_D5) << 5);
out |= (evgetin(LCD_D6) << 6);
out |= (evgetin(LCD_D7) << 7);
return out;
}
void lcd_enpulse()
{
usleep(SETUP);
evsetdata(LCD_EN, 1);
usleep(PULSE);
evsetdata(LCD_EN, 0);
usleep(HOLD);
}
void lcd_init(void)
{
evgpioinit();
// Data lines to inputs, control lines to outputs
lcd_ddr(0x0);
evsetddr(LCD_EN, 1);
evsetddr(LCD_RS, 1);
evsetddr(LCD_WR, 1);
// Set LCD_EN and LCD_RS low
evsetdata(LCD_EN, 0);
evsetdata(LCD_RS, 0);
// Set LCD_WR high
evsetdata(LCD_WR, 1);
usleep(15000);
lcd_command(0x38); // two rows, 5x7, 8 bit
usleep(4100);
lcd_command(0x38); // two rows, 5x7, 8 bit
usleep(100);
lcd_command(0x38); // two rows, 5x7, 8 bit
lcd_command(0x6); // cursor increment mode
lcd_wait();
//lcd_command(0x1); // clear display
// lcd_wait();
// lcd_command(0xc); // display on, blink off, cursor off
// lcd_wait();
lcd_command(0x2); // return home
evsetddr(LCD_BIAS, 1);
evsetdata(LCD_BIAS, 0);
}
void lcd_wait(void)
{
uint8_t in;
int i, dat, tries = 0;
lcd_ddr(0x0);
do {
// step 1, apply only RS & WR
evsetdata(LCD_RS, 0);
evsetdata(LCD_WR, 1); // low for write
lcd_enpulse();
usleep(1);
} while (in & 0x80 && tries++ < 5);
}
void lcd_command(uint16_t cmd)
{
lcd_ddr(0xff);
lcd_write(cmd);
evsetdata(LCD_WR, 0);
evsetdata(LCD_RS, 0);
lcd_enpulse();
}
void lcd_writechars(unsigned char *dat)
{
int i;
do {
lcd_wait();
lcd_ddr(0xff);
evsetdata(LCD_RS, 1);
evsetdata(LCD_WR, 0); // active low
lcd_write(*dat++);
lcd_enpulse();
} while (*dat);
}
int main(int argc, char *argv[])
{
char *temp = argv[1];
float sigStn = atof(temp);
float numBuf = (((sigStn-(-120))/(-70-(-120)))*100);
char buf[48];
if (numBuf >=9 && numBuf<=99) {
snprintf(buf, sizeof(buf), " Signal= %0.0f",numBuf);
strcat(buf,"% ");
} else {
snprintf(buf, sizeof(buf), " Signal= %0.0f",numBuf);
strcat(buf,"% ");
}
lcd_init();
lcd_command(LINE_1);
lcd_writechars(STS);
lcd_command(LINE_2);
if (numBuf > 100)
lcd_writechars(" Signal= 100% ");
else if(numBuf<0){
lcd_writechars(" Reconnecting ");
// lcd_writechars(" Signal = 0% ");
} else
lcd_writechars(buf);
lcd_command(LINE_3);
{while true; do
ping -c1 192.168.10.30 2>&1 /dev/null; //VPN IP
lcd_writechars("STS300");}
{if [[ ! $? ]]; then
lcd_writechars("VPN Lost");
fi;
sleep 10;
}
lcd_command(LINE_4);
lcd_writechars(BBPN);
return;
while (!feof(stdin)) {
unsigned char buf[512];
int i = 0;
lcd_wait();
if (i) {
// XXX: this seek addr may be different for different
// LCD sizes! -JO
lcd_command(0xa8); // set DDRAM addr to second row
} else
lcd_command(0x2); // return home
i = i ^ 0x1;
if (fgets(buf, sizeof(buf), stdin) != NULL) {
unsigned int len;
buf[0x27] = 0;
len = strlen(buf);
if (buf[len - 1] == '\n') buf[len - 1] = 0;
lcd_writechars(buf);
}
}
return 0;
}

The following lines of code in your program aren't C at all. They look like a fragment of shell script:
lcd_command(LINE_3);
{while true; do
ping -c1 192.168.10.30 2>&1 /dev/null; //VPN IP
lcd_writechars("STS300");}
{if [[ ! $? ]]; then
lcd_writechars("VPN Lost");
fi;
sleep 10;
}
This won't work. Rewrite this code in C. (The system() function may be helpful.)

Related

Segmentation Failure with print and write instructions, in Implementation between Fortran and C

I'm trying to call a C function from Fortran, using the iso_c_binding interoperability. However, I am getting a SegFault error when trying to use print and write statements. Without the print and write statements the code works fine, but I need these statements to create an output file with the simulation data. Does anyone know how to solve this problem?
Note: I am using Ubuntu 20.04, GFortran, and GCC to compile the respective source codes.
gcc -c subroutine_in_c.c
gfortran -o exec main.f90 subroutine_in_c.o -lwiringPi
main.f90:
PROGRAM main
USE, INTRINSIC:: iso_c_binding, ONLY: C_FLOAT
IMPLICIT NONE
REAL(KIND = 4) :: leitura_sensor = 0.0
INTERFACE
SUBROUTINE ler_sensores(s1) BIND(C)
USE, INTRINSIC :: iso_c_binding, ONLY: C_FLOAT
IMPLICIT NONE
REAL(KIND=C_FLOAT) :: s1
END SUBROUTINE ler_sensores
END INTERFACE
!print*, 'Call subroutine in C language'
call ler_sensores(leitura_sensor)
!print*, 'Return to main.f90'
OPEN(UNIT=1, FILE='output.txt', STATUS='unknown')
WRITE(1,*) leitura_sensor
CLOSE(UNIT=1)
END PROGRAM main
subroutine_in_c.c:
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiSPI.h>
#include <wiringPiI2C.h>
#define LCDADDR 0x27 //IIC LCD address
#define BLEN 1 //1--open backlight,0--close backlight
#define CHAN_CONFIG_SINGLE 8 //setup channel 0 as Single-ended input
#define SPICHANNEL 0 //MCP3008 connect to SPI0
#define ANALOGCHANNEL 0 //Potentiometer connect MCP3008 analog channel 0
#define ANALOGCHANNEL2 1
static int spifd;
static int i2cfd;
void
spiSetup (int spiChannel)
{
if ((spifd = wiringPiSPISetup (spiChannel, 10000)) < 0)
{
fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
}
int
myAnalogRead(int spiChannel,int channelConfig,int analogChannel)
{
if (analogChannel<0 || analogChannel>7)
return -1;
unsigned char buffer[3] = {1}; // start bit
buffer[1] = (channelConfig+analogChannel) << 4;
wiringPiSPIDataRW(spiChannel, buffer, 3);
return ( (buffer[1] & 3 ) << 8 ) + buffer[2]; // get last 10 bits
}
//write a word to lcd
void
write_word(int data)
{
int temp = data;
if ( BLEN == 1 )
temp |= 0x08;
else
temp &= 0xF7;
wiringPiI2CWrite(i2cfd, temp);
}
//send command to lcd
void
send_command(int comm)
{
int buf;
// Send bit7-4 firstly
buf = comm & 0xF0;
buf |= 0x04; // RS = 0, RW = 0, EN = 1
write_word(buf);
delay(2);
buf &= 0xFB; // Make EN = 0
write_word(buf);
// Send bit3-0 secondly
buf = (comm & 0x0F) << 4;
buf |= 0x04; // RS = 0, RW = 0, EN = 1
write_word(buf);
delay(2);
buf &= 0xFB; // Make EN = 0
write_word(buf);
}
//send data to lcd
void
send_data(int data)
{
int buf;
// Send bit7-4 firstly
buf = data & 0xF0;
buf |= 0x05; // RS = 1, RW = 0, EN = 1
write_word(buf);
delay(2);
buf &= 0xFB; // Make EN = 0
write_word(buf);
// Send bit3-0 secondly
buf = (data & 0x0F) << 4;
buf |= 0x05; // RS = 1, RW = 0, EN = 1
write_word(buf);
delay(2);
buf &= 0xFB; // Make EN = 0
write_word(buf);
}
//initialize the lcd
void
init()
{
send_command(0x33); // Must initialize to 8-line mode at first
delay(5);
send_command(0x32); // Then initialize to 4-line mode
delay(5);
send_command(0x28); // 2 Lines & 5*7 dots
delay(5);
send_command(0x0C); // Enable display without cursor
delay(5);
send_command(0x01); // Clear Screen
wiringPiI2CWrite(i2cfd, 0x08);
}
//clear screen
void
clear()
{
send_command(0x01); //clear Screen
}
//Print the message on the lcd
void
write(int x, int y, char data[])
{
int addr, i;
int tmp;
if (x < 0) x = 0;
if (x > 15) x = 15;
if (y < 0) y = 0;
if (y > 1) y = 1;
// Move cursor
addr = 0x80 + 0x40 * y + x;
send_command(addr);
tmp = strlen(data);
for (i = 0; i < tmp; i++) {
send_data(data[i]);
}
}
void
ler_sensores(float *s1)
{
int adc;
int adc2;
int i;
float voltage;
float voltage2;
char buf[5];
if (wiringPiSetup() < 0)
{
fprintf(stderr,"Can't init wiringPi: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
spiSetup(SPICHANNEL);//init spi
i2cfd = wiringPiI2CSetup(LCDADDR); //init i2c
init(); //init LCD
clear(); //clear screen
for (i = 0; i <25; i++) {
adc = myAnalogRead(SPICHANNEL,CHAN_CONFIG_SINGLE,ANALOGCHANNEL);
adc2 = myAnalogRead(SPICHANNEL, CHAN_CONFIG_SINGLE, ANALOGCHANNEL2);
voltage = adc/1024.*20.0;
write(0,0,"Ch Linear:");
sprintf(buf,"%2.2f",voltage);//float change to string
write(10,0,buf);//print voltage on lcd
write(15,0,"V");//print unit
write(0,1,"Ch Logarit:");
voltage2 = adc2/1024.*20.0;
sprintf(buf,"%2.2f",voltage2);
write(11,1, buf);
write(16,1,"V");
delay(1000);
}
*s1 = voltage;
}
Thank you in advance to everyone who helps.
This question probably deserves an answer even if the reason for the problem is the obscure one, identified by Craig Estay.
Gfortran's runtime library, called when using the print and write statements, contains calls to write() and having another C function called write will cause the gfortran runtime to call a wrong function.
It can easily be tested in a simple program like this:
testwrite.c:
#include "stdio.h"
void write(){
puts("my C write");
}
testwrite.f90:
print *,"test print"
write(*,*) "test write"
end
When using gfortran testwrite.c testwrite.f90, the output is:
my C write
my C write
my C write
my C write
The same output appears when using icc testwrite.c -c -o c.o and ifort c.o testwrite.f90.

How to turn on a LED with specific address on dot-matrix 74HC595?

I have problem when want to determine the address for each LED in dot-matrix 8x8 74HC595, im trying to light on only 1 LED specifically with the address. i have tried many tutorial and documentation but still no luck to light on only 1 LED with spesific location.
this is my circuit design :
https://www.sunfounder.com/learn/Super_Kit_V2_for_RaspberryPi/lesson-12-driving-dot-matrix-by-74hc595-super-kit-for-raspberrypi.html
my code with C:
#include <wiringPi.h>
#include <stdio.h>
#define SDI 0 //serial data input
#define RCLK 1 //memory clock input
#define SRCLK 2 //shift register clock input
unsigned char LED[8] ={0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void pulse(int pin)
{
digitalWrite(pin, 0);
digitalWrite(pin, 1);
}
void ShiftOUT(unsigned char byte)
{
int i;
for(i=0;i<8;i++)
{
// char a = byte & (0x80 >> i)) > 0;
digitalWrite(SDI, (( byte & (0x80 >> i)) > 0));
printf("%d", (( byte >> i > 0)));
pulse(SRCLK);
}
printf("\n","==================");
}
void init(void)
{
pinMode(SDI, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
digitalWrite(SDI, 0);
digitalWrite(RCLK, 0);
digitalWrite(SRCLK, 0);
}
int main(void)
{
int i;
if(wiringPiSetup() == -1)
{
printf("setup wiringPi failed !");
return 1;
}
init();
while(1)
{
for(i=0;i<8;i++)
{
ShiftOUT(LED[i]);
pulse(RCLK);
// printf("=======pull latch========");
// printf("\n");
delay(150);
}
delay(500);
}
return 0;
}
This code i tried will light on 1 row,i want to light on 1 LED with spesific location
Here is the link i use for simulation to addressing the LED : https://www.riyas.org/2013/12/online-led-matrix-font-generator-with.html
Any help?Thank you

Arduino serial works fine with Debian but hangs with Raspbian

I'm working on a personal home automation project.
On the server side, I have an Arduino Pro Mini with:
a 433 MHz TX module on pin 2
a 433 MHz RX module on pin 3
a DHT22 probe on pin 4 (with 10k pull-up)
a DHT22 probe on pin 5 (with 10k pull-up)
I have two absolutely identical of these modules; one will be the radio relay (and DHT "server") and the other a secondary DHT "server".
When it is linked to my laptop (Debian Wheezy) through an FTDI cable, it can read both local probes and switch my wall plugs on/off thanks to a C program I wrote. I'd like to use it from a Raspberry Pi. But on the Raspberry Pi (with the same FTDI cable on USB), it executes the first command I send and then hangs my terminal, forcing me to use CTRL+C.
Here is the sketch on the Arduino side (header) :
/**
* probe.h
*
* #author David Mézière <...>
*/
/**
* DHT probe result
*
*/
struct Probe {
float temperature;
float humidity;
};
Main file :
/**
* probe.ino
*
* #author David Mézière <...>
*/
#include "probe.h"
/**
* Uses DHT sensor library, from Adafruit.
* #see https://github.com/adafruit/DHT-sensor-library
*/
#include <DHT.h>
/**
* Uses RC Switch library, from sui77.
* #see https://github.com/sui77/rc-switch
*/
#include <RCSwitch.h>
// Pinout definitions
#define TX 2 // 433 MHz transmitter pin number
#define RX 3 // 433 MHz receiver pin number
#define PROBE1 4 // First DHT22 probe pin number
#define PROBE2 5 // Second DHT22 probe pin number
#define LED 13 // On-board status LED pin number
RCSwitch radio = RCSwitch();
// DHT probes definition
DHT dht1(PROBE1, DHT22);
DHT dht2(PROBE2, DHT22);
// Incomming command buffer
byte cmd[9];
/**
* Setup
*
* #return void
*/
void setup()
{
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
Serial.begin(9600);
Serial.setTimeout(1000); // doesn't fix the problem
// Attach receiver to interrupt 1, meaning pin 3
radio.enableReceive(1);
radio.enableTransmit(TX);
dht1.begin();
dht2.begin();
// Debug: Internal LED will blink 3 times rapidly to show when a reboot occurs.
for (int i = 0; i < 3; i++) {
digitalWrite(LED, HIGH);
delay(250);
digitalWrite(LED, LOW);
delay(250);
}
}
/**
* Loop
*
* #return void
*/
void loop()
{
if (Serial.available() == 9 && readCommand()) {
// Lights-up internal LED to show when a command has been executed
digitalWrite(LED, HIGH);
delay(1000);
digitalWrite(LED, LOW);
}
}
/**
* Query probe
*
* Query provided [dht] probe until [retry] times for both temperature and humidity.
*
* #param DHT dht Pointer to DHT object
* #param int retry Number of tries
* #return Probe Probe result (float temperature in °C, float humidity in %)
*/
Probe queryProbe(DHT* dht, int retry)
{
Probe probe;
// Query DHT22 probe for temperature, a maximum of [retry] times.
for (int t = 0; t < retry; t++) {
probe.temperature = dht->readTemperature(false);
if (!isnan(probe.temperature)) {
break;
}
delay(50);
}
// Query DHT22 probe for humidity, a maximum of [retry] times.
for (int h = 0; h < retry; h++) {
probe.humidity = dht->readHumidity();
if (!isnan(probe.humidity)) {
break;
}
delay(50);
}
return probe;
}
/**
* Read command
*
* If serial buffer contains 2 bytes, move them to a local buffer and return true. else return false.
*
* #return boolean
*/
boolean readCommand()
{
// Reads the current buffer
Serial.readBytes(cmd, 9);
// Calculates the check sum of payload
int sum = cmd[2] ^ cmd[3] ^ cmd[4] ^ cmd[5] ^ cmd[6] ^ cmd[7];
// Checking header and checksum a header of 0xBA 0xB1 means DHT query
if (cmd[0] == 0xBA && cmd[1] == 0xB1 && cmd[8] == sum) {
unsigned int module = cmd[2];
unsigned int probe = (cmd[4] << 24) + (cmd[5] << 16) + (cmd[6] << 8) + cmd[7];
Probe result;
switch (module) {
case 1:
// Selects the right probe
if (probe == 1) {
result = queryProbe(&dht1, 3);
} else if (probe == 2) {
result = queryProbe(&dht2, 3);
}
// Send status repport to client
Serial.print("1;");
Serial.print(module);
Serial.print(";");
Serial.print(probe);
Serial.print(";");
Serial.print(result.temperature);
Serial.print(";");
Serial.println(result.humidity);
Serial.flush(); // Doesn't fix the problem
break;
}
return true;
// A header of 0xBA 0xB2 means rf wall plugs query
} else if (cmd[0] == 0xBA && cmd[1] == 0xB2 && cmd[8] == sum) {
unsigned int proto = cmd[2];
unsigned int length = cmd[3];
unsigned int value = (cmd[4] << 24) + (cmd[5] << 16) + (cmd[6] << 8) + cmd[7];
radio.send(value, length);
// Send status repport to client
Serial.print("2;");
Serial.print(proto);
Serial.print(";");
Serial.print(length);
Serial.print(";");
Serial.print(value);
Serial.print(";");
Serial.println("OK");
Serial.flush(); // Doesn't fix the problem
return true;
} else {
Serial.println("KO");
Serial.flush(); // Doesn't fix the problem
return false;
}
}
And on the client side :
/**
* probe.c
*
* #author David Mézière <...>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <getopt.h>
const char* device;
static int module = 0; // uint_8 ?
static int probe = 0; // uint_8 ?
const char* proto;
static int length = 0; // uint_8 ?
static int value = 0; // uint_32 ?
static int verbose = 0; // uint_8 ?
void help()
{
printf("usage:\n");
printf("\n");
printf("probe [options] [arguments]\n");
printf("\n");
printf("options:\n");
printf(" -h|--help: Displays this help and exit\n");
printf(" -v|--verbose: Be more verbose\n");
printf("\n");
printf("arguments:\n");
printf(" -d|--device: string Serial device to use (ex: /dev/ttyUSB0)\n");
printf(" -m|--module: integer DHT22 module to query\n");
printf(" -p|--probe: integer DHT22 probe to query\n");
printf(" -r|--proto: string Radio / IR protocol\n");
printf(" -l|--length: integer Radio / IR value length in bits\n");
printf(" -a|--value: integer Radio / IR value\n");
printf("\n");
printf("examples:\n");
printf(" probe --device /dev/ttyUSB0 --module 1 --probe 1 : Will query first DHT22 probe of first module\n");
printf(" probe --proto radio1 --length 12 --value 5393 : Will send value 5393 on 12 bits over the air using protocol 1\n");
printf(" probe --proto ir11 --length 64 --value 3772793023 : Will send value 3772793023 on 64 bits by infra red using protocol 11\n");
}
void parseArgs(int argc, char **argv)
{
int c;
while (1) {
static struct option long_options[] = {
{"device", required_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"module", required_argument, 0, 'm'},
{"probe", required_argument, 0, 'p'},
{"proto", required_argument, 0, 'r'},
{"length", required_argument, 0, 'l'},
{"value", required_argument, 0, 'a'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long(argc, argv, "d:hm:p:v", long_options, &option_index);
/* Detect the end of the options. */
if (c == -1) {
break;
}
switch (c) {
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0) {
break;
}
printf("option %s", long_options[option_index].name);
if (optarg) {
printf (" with arg %s", optarg);
}
printf("\n");
break;
case 'd':
device = optarg;
break;
case 'h':
help();
exit(0);
break;
case 'm':
module = atoi(optarg);
break;
case 'p':
probe = atoi(optarg);
break;
case 'r':
proto = optarg;
break;
case 'l':
length = atoi(optarg);
break;
case 'a':
value = atoi(optarg);
break;
case 'v':
verbose = 1;
break;
case '?':
/* getopt_long already printed an error message. */
break;
default:
abort();
}
}
/* Print any remaining command line arguments (not options). */
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc) {
printf("%s ", argv[optind++]);
}
putchar('\n');
}
if (&device[0] == '\0') {
fprintf(stderr, "--device is mandatory\n");
exit(1);
} else if (verbose) {
printf("Device: %s\n", device);
}
if (verbose) {
printf("Querying probe %i of module %i.\n", probe, module);
}
}
void initSerial(int fd)
{
struct termios toptions;
/* get current serial port settings */
tcgetattr(fd, &toptions);
/* set 9600 baud both ways */
cfsetispeed(&toptions, B9600);
cfsetospeed(&toptions, B9600);
/* 8 bits, no parity, no stop bits */
toptions.c_cflag &= ~PARENB;
toptions.c_cflag &= ~CSTOPB;
toptions.c_cflag &= ~CSIZE;
toptions.c_cflag |= CS8;
/* Canonical mode */
toptions.c_lflag |= ICANON;
/* commit the serial port settings */
tcsetattr(fd, TCSANOW, &toptions);
}
int main(int argc, char **argv)
{
// Parses command line arguments
parseArgs(argc, argv);
int fd, n, i;
char buf[64] = "temp text";
/* open serial port */
fd = open(device, O_RDWR | O_NOCTTY);
if (verbose) {
printf("Device %s opened as %i\n", device, fd);
}
/*
* Note: Most Arduinos models will reboot upon connection, and they need
* some time for it. I use a pro/mini that doesn't, so i commented it out.
*/
// usleep(3500000);
// Sets the serial port settings (9600 bps, 8 bits, no parity, no stop bits)
initSerial(fd);
/**
* 72 bits
* | Header | Param 1 | Param 2 | Param 3 | sum |
* | 16 b | 8 b | 8 b | 32 b | 8 b |
* Cas 1 : Requête DHT | 0xba 0xb1 | module | 0x00 | sonde | sum |
* Cas 2 : Requête radio | 0xba 0xb2 | proto | length | value | sum |
* Cas 3 : Requête IR | 0xba 0xb3 | proto | length | value | sum |
*/
unsigned char oBuf[9];
// printf("%s\n", proto);
// printf("%i\n", length);
if (module > 0 && probe > 0) {
if (verbose) {
printf("DHT mode\n");
}
oBuf[0] = 0xBA;
oBuf[1] = 0xB1; // DHT query
oBuf[2] = module;
oBuf[3] = 0x00;
oBuf[4] = (probe >> 24) & 0xFF;
oBuf[5] = (probe >> 16) & 0xFF;
oBuf[6] = (probe >> 8) & 0xFF;
oBuf[7] = probe & 0xFF;
oBuf[8] = oBuf[2];
oBuf[9] = '\n';
// Calculates the XOR sum
for (i = 3; i < 8; i++) {
oBuf[8] ^= oBuf[i];
}
// sprintf(oBuff, "%c%c%c%c%c%c", 0xba, 0xb1, module, 0x00, probe, sum);
} else if (strcmp((const char*)proto, "radio1") == 0 && length > 0) {
if (verbose) {
printf("Radio mode\n");
}
oBuf[0] = 0xBA;
oBuf[1] = 0xB2; // Radio query
oBuf[2] = 0x01; // Protocol 1
oBuf[3] = length;
oBuf[4] = (value >> 24) & 0xFF;
oBuf[5] = (value >> 16) & 0xFF;
oBuf[6] = (value >> 8) & 0xFF;
oBuf[7] = value & 0xFF;
oBuf[8] = oBuf[2];
oBuf[9] = '\n';
// Calculates the XOR sum
for (i = 3; i < 8; i++) {
oBuf[8] ^= oBuf[i];
}
} else {
if (verbose) {
printf("Unknown mode\n");
}
}
/* Send the buffer */
write(fd, oBuf, 9);
/* Receive string from Arduino */
n = read(fd, buf, 64);
/* insert terminating zero in the string */
buf[n] = 0;
if (verbose) {
printf("%i bytes read, buffer contains: %s\n", n, buf);
} else {
printf("%s", buf);
}
return 0;
}
I compile it using just gcc probe.c -o probe.
On Debian, I can use the system as much as I want, it works:
dmeziere#portable2-wlan:~/dev/probe$ gcc probe.c -o probe
dmeziere#portable2-wlan:~/dev/probe$ ./probe --device /dev/ttyUSB0 --module 1 --probe 1
1;1;1;23.60;43.10
dmeziere#portable2-wlan:~/dev/probe$ ./probe --device /dev/ttyUSB0 --module 1 --probe 2
1;1;2;23.60;38.50
dmeziere#portable2-wlan:~/dev/probe$ ./probe --device /dev/ttyUSB0 --proto radio1 --length 24 --value 5396
2;1;24;5396;OK
dmeziere#portable2-wlan:~/dev/probe$ ./probe --device /dev/ttyUSB0 --proto radio1 --length 24 --value 5393
2;1;24;5393;OK
On Raspbian, the first call works, but the second hangs my terminal and I have to do CTRL+C:
dmeziere#raspberrypi:~/probe$ ./probe --device /dev/ttyUSB0 --module 1 --probe 1
1;1;1;23.90;39.00
dmeziere#raspberrypi:~/probe$ ./probe --device /dev/ttyUSB0 --module 1 --probe 2
^C
I found it !
It seems like on Raspbian, the communications were terminated by a NULL character. But not on Debian. And this NULL character was polluting my calculations of incomming buffer length. So i ended up by eventually suppress it on the Arduino side :
boolean readCommand()
{
// Reads the current buffer
Serial.readBytes(cmd, 9);
// If sender sends a null character, remove it.
int test = Serial.peek();
if (test == 0x00) {
test = Serial.read();
}
// ...
}

Error: identifier "LCD_E_PORT" is undefined

Why I get the error: identifier "LCD_E_PORT" is undefined in this code:
#include <msp430f5438a.h>
#include "IO_functions.h"
#define LCD_E_PORT PORT_6
#define LCD_E PIN_4
#include "LCD1602.h"
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P4DIR = 0x03;
P4OUT = 0x00;
output_bit(PORT_4, PIN_7, 1);
output_bit(PORT_4, PIN_7, 0);
lcd_send_nibble(0x0f);
while(1)
{
P4OUT ^= BIT0;
__delay_cycles(500000);
}
}
Since I have defined LCD_E_PORT at the top of my code I don't understand where this error comes from.
This is LCD1602.c in which I am using LCD_E_PORT:
#include <msp430f5438a.h>
#include "LCD1602.h"
#include "IO_functions.h"
void lcd_send_nibble(unsigned char nibble)
{
output_bit(LCD_DB4_PORT, LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5_PORT, LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6_PORT, LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7_PORT, LCD_DB7, !!(nibble & 8));
__delay_cycles(8);
output_bit(LCD_E_PORT, LCD_E, 1);
__delay_cycles(16);
output_bit(LCD_E_PORT, LCD_E, 0);
}
void lcd_send_byte(unsigned char data_instr, unsigned char data)
{
output_bit(LCD_RS_PORT, LCD_RS, 0);
__delay_cycles(480);
if(data_instr == DATA)
output_bit(LCD_RS_PORT, LCD_RS, 1);
else
output_bit(LCD_RS_PORT, LCD_RS, 0);
__delay_cycles(8);
output_bit(LCD_E_PORT, LCD_E, 0);
lcd_send_nibble(data >> 4);
lcd_send_nibble(data & 0x0F);
}
void lcd_init(void)
{
unsigned char i;
output_bit(LCD_RS_PORT, LCD_RS, 0);
output_bit(LCD_E_PORT, LCD_E, 0);
__delay_cycles(120000);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
__delay_cycles(25000);
}
lcd_send_nibble(0x02);
lcd_send_byte(INSTR, 0x28);
__delay_cycles(25000);
lcd_send_byte(INSTR, 0x0C);
__delay_cycles(25000);
lcd_send_byte(INSTR, 0x01);
__delay_cycles(25000);
lcd_send_byte(INSTR, 0x06);
__delay_cycles(25000);
}
As per the updated code, the definition of LCD_E_PORT is not visible from LCD1602.c file.
You might want to add the #define in the header file (LCD1602.h or any other, at your choice) itself which will be included in all the source files making use of the macro.

Undefined reference to `usbInit' in C AVR

I use v-usb library for my project.
I wrote code and i want compile it, but unfortunately I have an error which I'm unable to resolve.
Here is my screen-shot:
Description Resource Path Location Type
make: *** [USB_module.elf] Error 1 USB_module C/C++ Problem
undefined reference to `usbInit' main.c /USB_module C/C++ Problem
undefined reference to `usbMsgPtr' main.c /USB_module C/C++ Problem
undefined reference to `usbPoll' main.c /USB_module C/C++ Problem
This situation is for me strange because i have in header this:
#include "usbconfig.h"
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h"
And usbdrv/usbdrv.h defines the USBpoll function:
Shouldn't the compiler be able to compile it?
Here is my project: http://goo.gl/P6ujK
And here is my entire workspace directory: http://minus.com/mbhTkJuvOK#1
Here is my code: main.c:
/*
* main.c
*
* Created on: 25-01-2012
* Author: Bordeux
*/
#define F_CPU 12000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include "usbconfig.h"
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h"
#define DDS1_SDA (1<<1) //PORTB1
#define DDS_SCL (1<<3) //PORTB3
#define DDS_UPDATE (1<<4) //PORTB4
static uchar usb_val;
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) //sends len bytes to DDS_SDA
{
uchar i;
uchar b;
uchar adr=0;
while (len!=0)
{
b=1;
for (i=0; i<8; i++)
{
if (b & data[adr])
{
PORTB = (PORTB | DDS1_SDA) & ~DDS_SCL;
PORTB = PORTB | DDS_SCL;
}
else
{
PORTB = PORTB & (~DDS1_SDA & ~DDS_SCL);
PORTB = PORTB | DDS_SCL;
}
b=b<<1;
}
len--;
adr++;
}
if (usb_val)
{
PORTB = PORTB | DDS_UPDATE;// update DDS
PORTB = PORTB & ~DDS_UPDATE;
}
return 1;
}
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
static uchar replyBuf[3];
usbMsgPtr = replyBuf;
if(rq->bRequest == 0) // ECHO value
{
replyBuf[0] = data[2]; // rq->bRequest identical data[1]!
replyBuf[1] = data[3];
return 2;
}
if(rq->bRequest == 1) // set port directions
{
// DDRA = data[2];
DDRB = data[3];
DDRD = data[4] & (~USBMASK & ~(1 << 2)); // protect USB interface
return 0;
}
if(rq->bRequest == 2) // read ports
{
// replyBuf[0] = PINA;
replyBuf[1] = PINB;
replyBuf[2] = PIND;
return 3;
}
if(rq->bRequest == 3) // read port states
{
// replyBuf[0] = PORTA;
replyBuf[1] = PORTB;
replyBuf[2] = PORTD;
return 3;
}
if(rq->bRequest == 4) // set ports
{
// PORTA = data[2];
PORTB = data[3];
PORTD = data[4];
return 0;
}
if(rq->bRequest == 5) // use usbFunctionWrite to transfer len bytes to DDS
{
usb_val = data[2]; // usb_val!=0 => DDS update pulse after data transfer
return 0xff;
}
if(rq->bRequest == 6)
{
PORTB = PORTB | DDS_UPDATE; // issue update pulse to DDS
PORTB = PORTB & ~DDS_UPDATE;
return 0;
}
replyBuf[0] = 0xff; // return value 0xff => command not supported
return 1;
}
int main(void)
{
wdt_enable(WDTO_1S); // set Watchdog Timer
odDebugInit();
PORTB=0xe0; // Set PortB 0-4 zero
DDRB=0x1f; // Set PORTB 0-4 output
PORTD = 0; /* no pullups on USB pins */
DDRD = ~USBMASK & ~(1 << 2); /* all outputs except USB data and PD2 = INT0 */
usbInit();
sei();
for(;;) /* main event loop */
{
wdt_reset(); // restart watchdog timer
usbPoll();
}
return 0;
}
solution:
mv usbdrv.c usbdrv.cpp
or compile with avr-g++
You need to link against whatever file supplies usbInit etc., from the looks of your screen shots you've shown the file usbdrv.c, but not actually compiled/linked it into your project. Only usbdrv.h is showing in the tree view.
#includeing the header file shows the compiler the declaration of the function, you need to make sure it sees the definition somewhere too.
you could also have included usbdrv.h in extern "C":
extern "C" {
#include "usbdrv.h";
}

Resources