atmega128 helperror: expected ';' before numeric constant - atmega

Why is this happening?
I do not see any problems.
I can not sense what to fix.
help me!
../1105-1.c: In function 'E_Pulse':
../1105-1.c:23:2: error: expected ';' before numeric constant
../1105-1.c:25:2: error: expected ';' before numeric constant
These errors are per function.
#include<avr/io.h>
#include<util/delay.h>
#define TLCD_RS PORTB.0
#define TLCD_RW PORTB.1
#define TLCD_E PORTB.2
#define TLCD_EN{TLCD_E = 0 ; TLCD_E = 1 ; }
#define DATA PORTC
void Port_Init(void);
void E_Pulse(void);
void Func_Set(void);
void TLCD_DATA(unsigned char);
void Init_LCD(void);
void Port_Init(void)
{
DDRB = 0xff;
DDRC = 0xff;
}
void E_Pulse(void)
{
TLCD_E = 1;
_delay_ms(5);
TLCD_E = 0;
}
void TLCD_DATA(unsigned char data)
{
DATA = data;
TLCD_EN;
}
void Init_LCD(void)
{
TLCD_E = 0;
_delay_ms(15);
Func_Set();
_delay_ms(10);
Func_Set();
_delay_ms(150);
Func_Set();
TLCD_DATA(0x0f);
E_Pulse();
TLCD_DATA(0x06);
E_Pulse();
TLCD_DATA(0x01);
E_Pulse();
}
void lcd_char(char s)
{
TLCD_RS = 1;
TLCD_DATA(s);
E_Pulse();
}
void main(void)
{
Port_Init();
Init_LCD();
lcd_char('1');
lcd_char('2');
lcd_char('3');
lcd_char('4');
while(1);
}

Getting the same error on lines 23 and 25 is a massive clue.
Commonly the error line number refers to the line after the one with the error, because that is where things become obviously wrong to the compiler.
Reproducing that function, and expanding out the macro gives the following code
void E_Pulse(void)
{
PORTB.2 = 1;
_delay_ms(5);
PORTB.2 = 0;
}
PORTB.2 is invalid code, it looks a bit like accessing a struct but struct elements can't be numbers. So the compiler gets confused and throws errors, the semicolon was a bit misleading, generally it guesses better.
This isn't the way you control GPIO pins using the AVR system. I have linked to a reasonable looking tutorial below.
http://www.elecrom.com/avr-tutorial-2-avr-input-output/

Related

Variable gets a value as if the shift command had not been executed

This is my simple program in the infinite loop that only measures the voltage from the mains and saves the value in the variable ulp_vars.pin2.val. The problem is that at some undefined intervals but certainly under one second this variable gets a value as if the shift command had not been executed. This is a simplified example from the HULP library, and in that original example, I didn't notice anything like this happening. Does anyone have any idea why this is happening?
#include "hulp_arduino.h"
#define PIN_ADC_PIN2 GPIO_NUM_34
#define PIN2_OVERSAMPLE_SHIFT 3
RTC_DATA_ATTR struct {
ulp_var_t pin2;
} ulp_vars;
void ulp_init()
{
enum {
LBL_PIN2_OVERSAMPLE_LOOP,
LBL_LOOP,
};
const ulp_insn_t program[] = {
M_LABEL(LBL_LOOP),
I_STAGE_RST(),//
I_MOVI(R0, 0),//These are just attempts to solve the problem.
I_MOVI(R1, 0),//
I_MOVI(R2, 0),//
I_MOVI(R3, 0),
M_LABEL(LBL_PIN2_OVERSAMPLE_LOOP),
I_ANALOG_READ(R1, PIN_ADC_PIN2),
I_ADDR(R0, R0, R1),
I_STAGE_INC(1),
M_BSLT(LBL_PIN2_OVERSAMPLE_LOOP, (1 << PIN2_OVERSAMPLE_SHIFT)),
I_RSHI(R0, R0, PIN2_OVERSAMPLE_SHIFT),
I_MOVI(R3, 0),
I_PUT(R0, R3, ulp_vars.pin2),
I_GPIO_SET(GPIO_NUM_14, 1),//This produces 1.43 uS pulse
I_GPIO_SET(GPIO_NUM_14, 0),// for test, nothing else !
I_DELAY(10),
I_BXI(LBL_LOOP),
};
ESP_ERROR_CHECK(hulp_configure_pin(GPIO_NUM_14, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 1));
ESP_ERROR_CHECK(hulp_configure_analog_pin(PIN_ADC_PIN2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12));
//ESP_ERROR_CHECK(hulp_ulp_load(program, sizeof(program), 1000UL * ULP_WAKEUP_INTERVAL_MS, 0));
size_t size = sizeof(program) / sizeof(ulp_insn_t);
ESP_ERROR_CHECK(ulp_process_macros_and_load(0, program, &size));
ESP_ERROR_CHECK(hulp_ulp_run(0));
}
void setup()
{
Serial.begin(115200);
if (hulp_is_deep_sleep_wakeup())
{
Serial.print("Wakeup !");
}
else
{
ulp_init();
}
}
void loop() {
Serial.println(ulp_vars.pin2.val);
}
Solved. If you need an infinite loop in the ULP program at the beginning of the program add:
I_WR_REG_BIT (RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
and so you forbade the influence of the start timer on the flow of the program!

Overloading function handling char and String

I'm making a function to handle a message, then print the message using Serial.println(). I have it working, but ran into an issue I can't explain. The first sample code below works, the second (swapping the order of my function declaration) will compile and load, but causes the Teensy 4.1 to crash. I'm using PlatformIO on VSCode.
Can anyone tell me what is wrong with the second code, and why it will compile without error, but not run?
This works:
#include <Arduino.h>
void LogMsg(const char *msg){
Serial.println(msg);
}
void LogMsg(String s){ LogMsg(s.c_str()); }
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("reset");
}
void loop() {
// put your main code here, to run repeatedly:
String str3 = "testing string cat ";
uint32_t var = 12345;
LogMsg(str3 + var);
delay(500);
}
This compiles, loads, but crashes, causing continuous resets:
#include <Arduino.h>
void LogMsg(String s){ LogMsg(s.c_str()); } // <-- swapped order
void LogMsg(const char *msg){ // <-- swapped order
Serial.println(msg);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("reset");
}
void loop() {
// put your main code here, to run repeatedly:
String str3 = "testing string cat ";
uint32_t var = 12345;
LogMsg(str3 + var);
delay(500);
}
Edit: The definition of void LogMsg(String s) was changed to reflect error in original and the simplification suggested by #hcheung. Behavior remains the same. The first instance works, the second crashes.
C strings are terminated with '\0'. So toCharArray() will append a null character to your Ardunio String. Otherwise you would have to provide a length with the char pointer everytime you want to use that string.
Your char array must be big enough to fit this extra character or you will cause an access violation if toCharArray does not throw an exception first.

What is rosidl_runtime_c__double__Sequence type?

I'm trying to use a teensy 4.1 as an interface between an encoder and ROS thanks to micro-ros (arduino version).
I would like to publish position of a wheel to the /jointState topic with the teensy but there is no example on the micro-ros arduino Github repo.
I've tried to inspect the sensormsgs/msg/jointState message struct but everything is a bit fuzzy and I don't understand how to make it works. I can't understand what is rosidl_runtime_c__double__Sequence type.
I've tried several things but I always get an error about operand types
no match for 'operator=' (operand types are 'rosidl_runtime_c__String' and 'const char [18]')
msg.name.data[0] = "drivewhl_1g_joint";
Here is my arduino code
#include <micro_ros_arduino.h>
#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <sensor_msgs/msg/joint_state.h>
rcl_publisher_t publisher;
sensor_msgs__msg__JointState msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;
#define LED_PIN 13
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}
void error_loop(){
while(1){
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
delay(100);
}
}
void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
RCLC_UNUSED(last_call_time);
if (timer != NULL) {
RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
//
//Do not work
//msg.name=["drivewhl_1g_joint","drivewhl_1d_joint","drivewhl_2g_joint","drivewhl_2d_joint"];
//msg.position=["1.3","0.2", "0","0"];
msg.name.size = 1;
msg.name.data[0] = "drivewhl_1g_joint";
msg.position.size = 1;
msg.position.data[0] = 1.85;
}
}
void setup() {
set_microros_transports();
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
delay(2000);
allocator = rcl_get_default_allocator();
//create init_options
RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));
// create node
RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));
// create publisher
RCCHECK(rclc_publisher_init_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, JointState),
"JointState"));
// create timer,
const unsigned int timer_timeout = 1000;
RCCHECK(rclc_timer_init_default(
&timer,
&support,
RCL_MS_TO_NS(timer_timeout),
timer_callback));
// create executor
RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
RCCHECK(rclc_executor_add_timer(&executor, &timer));
}
void loop() {
delay(100);
RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}
I'm a beginner with Ros and C, it may be a very dumb question but I don't know how to solve it. Thanks for your help !
rosidl_runtime_c__String__Sequence is a structure used to old string data that is to be transmitted. Specifically it is a sequence of rosidl_runtime_c__String data. You're running into an error because rosidl_runtime_c__String is also a struct itself with no custom operators defined. Thus, your assignment fails since the types are not directly convertible. What you need to do instead is use the rosidl_runtime_c__String.data field. You can see slightly more info here
void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
RCLC_UNUSED(last_call_time);
if (timer != NULL) {
//msg.name=["drivewhl_1g_joint","drivewhl_1d_joint","drivewhl_2g_joint","drivewhl_2d_joint"];
//msg.position=["1.3","0.2", "0","0"];
msg.name.size = 1;
msg.name.data[0].data = "drivewhl_1g_joint";
msg.name.data[0].size = 17; //Size in bytes excluding null terminator
msg.position.size = 1;
msg.position.data[0] = 1.85;
RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
}
}
I also spent quite some time trying to get publishing JointState message from my esp32 running microros, and also couldn't find working example. Finally, i was successful, maybe it will help someone.
In simple words:
.capacity contains max number of elements
.size contains actual number of elements (strlen in case of string)
.data should be allocated as using malloc as .capacity * sizeof()
each string within sequence should be allocated separately
This is my code that allocates memory for 12 joints, named j0-j11. Good luck!
...
// Declarations
rcl_publisher_t pub_joint;
sensor_msgs__msg__JointState joint_state_msg;
...
// Create publisher
RCCHECK(rclc_publisher_init_default(&pub_joint, &node,
ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, JointState),
"/hexapod/joint_state"));
//Allocate memory
joint_state_msg.name.capacity = 12;
joint_state_msg.name.size = 12;
joint_state_msg.name.data = (std_msgs__msg__String*) malloc(joint_state_msg.name.capacity*sizeof(std_msgs__msg__String));
for(int i=0;i<12;i++) {
joint_state_msg.name.data[i].data = malloc(5);
joint_state_msg.name.data[i].capacity = 5;
sprintf(joint_state_msg.name.data[i].data,"j%d",i);
joint_state_msg.name.data[i].size = strlen(joint_state_msg.name.data[i].data);
}
joint_state_msg.position.size=12;
joint_state_msg.position.capacity=12;
joint_state_msg.position.data = malloc(joint_state_msg.position.capacity*sizeof(double));
joint_state_msg.velocity.size=12;
joint_state_msg.velocity.capacity=12;
joint_state_msg.velocity.data = malloc(joint_state_msg.velocity.capacity*sizeof(double));
joint_state_msg.effort.size=12;
joint_state_msg.effort.capacity=12;
joint_state_msg.effort.data = malloc(joint_state_msg.effort.capacity*sizeof(double));
for(int i=0;i<12;i++) {
joint_state_msg.position.data[i]=0.0;
joint_state_msg.velocity.data[i]=0.0;
joint_state_msg.effort.data[i]=0.0;
}
....
//Publish
RCSOFTCHECK(rcl_publish(&pub_joint, &joint_state_msg, NULL));

seg fault / pointer assistance

so i know the bases of programming, i have a decent amount of experience with java, but im learning C for school right now. I still dont completely understand the whole pointer aspect, which is what im sure caused the fault. This program works fine when run on my computer, but when i try and run it on my schools unix shell it gives me a seg fault. if someone could please explain to me why or how ive misused hte pointers, that would help me greatly.
//Matthew Gerton
//CS 222 - 002
//10/10/14
//HW Six
//libraries
#include<stdio.h>
#include<string.h>
#define max_Length 256
//prototypes
void decode(char *a, char *b);
void trimWhite(char *a);
void encode(char *a, char *b);
int main(void)
{
//character arrays
char coded[max_Length], decoded[max_Length];
//decode the sample phrase
char sample[] = {'P','H','H','W','D','W','C','R','R','F','D','Q','F','H','O','H','G','J',
'R','W','R','P','H','W','U','R','K','R','W','H','O','U','R','R','P','I','R','X','U'};
decode(sample, decoded);
//scans a user input string to decode, and decodes it
printf("\nPlease enter a phrase to decode: ");
gets(coded);
trimWhite(coded);
decode(coded, decoded);
//scans a user input phrase to encode
printf("\nPlease enter a phrase to encode: ");
gets(coded);
trimWhite(coded);
encode(coded, decoded);
}
//removes any spaces from the input
void trimWhite(char *a)
{
char temp[max_Length];
int z=0, y=0;
while(a[z]!='\0')
{
if(a[z]!=' ')
{
temp[y]=a[z];
y++;
}
z++;
}
temp[y] = '\0';
strcpy(a,temp);
}
//decodes any phrase
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
n=n+32;
if(n<=99)
n=n+23;
else
n = n-3;
b[i]= (char) n;
i++;
}
b[i]='\0';
printf("Coded message: %s\n", a);
printf("Decoded message: %s\n", b);
}
//codes an input phrase
void encode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
strcpy(b,a);
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
a[i] = (char)(n+32);
if((n>120)
a[i] = (char)(n-23);
else
a[i] = (char)((n+3);
i++;
}
printf("Coded message: %s\n", a);
}
Your main problem is here:
char sample[] = {'P','H','H', /* snip */ ,'R','X','U'};
The sample[] array is not zero-terminated which may cause the decode() function to copy many more characters than intended, thus overwriting other variables. You need to explicitly add a terminating zero when using an initializer-list:
char sample[] = {'P','H','H', /* ... */ ,'R','X','U',0};
Or you can initialize the array using a string literal, which does include a terminating zero:
char sample[] = "PHHWDWCRRFDQFHOHGJRWRPHWURKRWHOURRPIRXU";
You should probably read "Why is the gets function dangerous".
...
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
Also note that the size of the array is lost when it is passed to a function. The function only receives a pointer to its first element. The memset() call above will only zero sizeof(char*) bytes (usually 4 or 8). This doesn't matter though because, as far as I can tell, you only need to zero the first byte. You could simply write:
b[0] = 0;

Writing Data to Arduino EEPROM

This is a follow-up to the post here - Writting data to the Arduino's onboard EEPROM
I just tried using the snippets in the URL but wouldn't work. Please help me fix the below error.
write_to_eeprom.cpp:8:5: error: expected unqualified-id before '[' token
write_to_eeprom.cpp: In function 'void setup()':
write_to_eeprom.cpp:12:16: error: 'stringToWrite' was not declared in this scope
write_to_eeprom.cpp: In function 'void loop()':
write_to_eeprom.cpp:22:33: error: invalid conversion from 'uint8_t {aka unsigned char}' to 'char*' [-fpermissive]
write_to_eeprom.cpp: In function 'void EEPROM_write(void*, byte)':
write_to_eeprom.cpp:32:32: error: 'void*' is not a pointer-to-object type
Here is the code
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
char[] stringToWrite = "Test";
void setup() {
lcd.begin(16, 2);
delay(5000);
EEPROM_write(stringToWrite, strlen(stringToWrite));
}
void loop() {
delay(10000);
int addr = 0;
byte datasize = EEPROM.read(addr++);
char stringToRead[0x20]; // allocate enough space for the string here!
char * readLoc = stringToRead;
for (int i=0;i<datasize; i++) {
readLoc = EEPROM.read(addr++);
readLoc++;
}
}
// Function takes a void pointer to data, and how much to write (no other way to know)
// Could also take a starting address, and return the size of the reach chunk, to be more generic
void EEPROM_write(void * data, byte datasize) {
int addr = 0;
EEPROM.write(addr++, datasize);
for (int i=0; i<datasize; i++) {
EEPROM.write(addr++, data[i]);
}
}
Well, you need to fix your code:
line 8 -- [] needs to go AFTER stringToWrite
line 12 -- should get better after fixing line 8
line 22 -- you need to dereference readLoc. add a '*' before it.
line 32 -- your parameter "data" is a pointer to void, which has no size. Because of that, you will not be able to use it as an array. You could change the declaration to:
void EEPROM_write(char * data, byte datasize)
That fixes the compiler errors. Taking a quick look at the semantics of the code seems to be doing what you want. Good luck.

Resources