Why does arduino ide tell me I have too many initiallizers? - c++

I have a sinewave look up table in the form of a list in my arduino program. I used a calculator to generate it. I have confirmed the length of the list with a python 2 shell,
>>>a=[all the variables separated by commas]
>>>len(a)
131300 is the value returned as the number of values in 'a'. So why when I run this code:
#include <Wire.h>//Include the Wire library to talk I2C
//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
#define MCP4725_ADDR 0x60
//Sinewave Tables were generated using this calculator:
//http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml
int lookup = 0;//varaible for navigating through the tables
int sintab2[131300]=
{
/* This is where I put my list. */
};
void setup()
{
Wire.begin();
// Set A2 and A3 as Outputs to make them our GND and Vcc,
//which will power the MCP4725
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
digitalWrite(A2, LOW);//Set A2 as GND
digitalWrite(A3, HIGH);//Set A3 as Vcc
}
//---------------------------------------------------
void loop()
{
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(64); // cmd to update the DAC
Wire.write(sintab2[lookup] >> 4); // the 8 most significant bits...
Wire.write((sintab2[lookup] & 15) << 4); // the 4 least significant bits...
Wire.endTransmission();
lookup = (lookup + 1) & 147454;
}
Why am I getting this error, the python shell is telling me my list is 131300 values long.
DAC_SINE.cpp:6607:1: error: too many initializers for 'int [16383]'
If it is needed I can post my list. The values I entered into the daycounter.com calculator with 131299 for the number of points, 4095 for the max amplitude, 20 numbers per row, and decimal format. Please help.

Related

Problem using SevSegShift library with ESP32 and 74HC595

I'm trying to build a digital clock using ESP32. I cannot use the TM1637 display module because it's too small. So I'm using a generic common anode 4 digit 7 segment display. I used the Arduino SevSeg library on ESP32 and it worked perfectly. However, it consumed a lot of GPIO pins. Hence I used two 74HC595 registers and connected them exactly as described in the SevSegShift library (a fork of SevSeg library but with shift registers), like this:
Unfortunately, when I run the code, I get wrong output. No matter what number or characters I try to display, only the "b" segment of the corresponding digits are turned on, all other segments of all digits are turned off. For ex, if I try to display "1111", only the "b" segment of all digits are turned on, rest all segments of all digits are turned off. As a result only upper half of "1111" is displayed on the 7 segment display.
Here's the code:
#include <Arduino.h>
#include <SevSegShift.h>
#define SHIFT_PIN_DS 5 /* Data input PIN */
#define SHIFT_PIN_STCP 19 /* Shift Register Storage PIN */
#define SHIFT_PIN_SHCP 18 /* Shift Register Shift PIN */
SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP); //Instantiate a seven segment controller object (with Shift Register functionality)
void setup() {
// put your setup code here, to run once:
byte numDigits = 4;
byte digitPins[] = {8+2, 8+5, 8+6, 2}; // of ShiftRegister(s) | 8+x (2nd Register)
byte segmentPins[] = {8+3, 8+7, 4, 6, 7, 8+4, 3, 5}; // of Shiftregister(s) | 8+x (2nd Register)
bool resistorsOnSegments = false;
byte hardwareConfig = COMMON_ANODE;
bool updateWithDelays = false;
bool leadingZeros = false;
bool disableDecPoint = false;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
}
void loop() {
// put your main code here, to run repeatedly:
sevseg.setNumber(1111, 0);
sevseg.refreshDisplay();
delay(1);
}
What am I doing wrong? Is the circuit layout given above correct? More importantly, does the SevSegShift library work with ESP32?

ADXL345 library for sparkfun redboard turbo giving wrong readings

I am running an ADXL345 using I2C on both a sparkfun redboard turbo(processor samd21g18) and an old arduino uno (processor mega16u2). The library and sketch I'm using on both boards are same with the exception that the serial port is changed to SerialUSB to accommodate the redboard.
The issue appears to be that the uno interprets the xyz registers (2 bytes per axis in registers 0x32 - 0x37) as 16 bit twos compliment (as per the datasheet) and the redboard does not. The uno's output is correct and the redboard output which is incorrect is all positive integer output.
The image below shows the output for the redboard on left and uno on right for same relative position of the ADXL345).
I believe the offending code is in the following library code.
/*********************** READING ACCELERATION ***********************/
/* Reads Acceleration into Three Variables: x, y and z */
void ADXL345::readAccel(int *xyz){
readAccel(xyz, xyz + 1, xyz + 2);
}
void ADXL345::readAccel(int *x, int *y, int *z) {
readFrom(ADXL345_DATAX0, ADXL345_TO_READ, _buff); // Read Accel Data from ADXL345
// Each Axis # All g Ranges: 10 Bit Resolution (2 Bytes)
*x = (((int)_buff[1]) << 8) | _buff[0];
*y = (((int)_buff[3]) << 8) | _buff[2];
*z = (((int)_buff[5]) << 8) | _buff[4];
}
The sketch code is as follows:
#include <SparkFun_ADXL345.h>
/*********** COMMUNICATION SELECTION ***********/
/* Comment Out The One You Are Not Using */
//ADXL345 adxl = ADXL345(10); // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345(); // USE FOR I2C COMMUNICATION
/****************** INTERRUPT ******************/
/* Uncomment If Attaching Interrupt */
//int interruptPin = 2; // Setup pin 2 to be the interrupt pin (for most Arduino Boards)
/******************** SETUP ********************/
/* Configure ADXL345 Settings */
void setup(){
SerialUSB.begin(9600); // Start the SerialUSB terminal
SerialUSB.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
SerialUSB.println();
adxl.powerOn(); // Power on the ADXL345
adxl.setRangeSetting(2); // Give the range settings
// Accepted values are 2g, 4g, 8g or 16g
// Higher Values = Wider Measurement Range
// Lower Values = Greater Sensitivity
}
/****************** MAIN CODE ******************/
/* Accelerometer Readings and Interrupt */
void loop(){
// Accelerometer Readings
int x,y,z;
adxl.readAccel(&x, &y, &z); // Read the accelerometer values and store them in variables declared above x,y,z
// Output Results to SerialUSB
/* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */
SerialUSB.print(x);
SerialUSB.print(", ");
SerialUSB.print(y);
SerialUSB.print(", ");
SerialUSB.println(z);
adxl.printAllRegister();
delay(10);
}
The code that declares _buff[] which is in the header .h file:
private:
void writeTo(byte address, byte val);
void writeToI2C(byte address, byte val);
void writeToSPI(byte address, byte val);
void readFrom(byte address, int num, byte buff[]);
void readFromI2C(byte address, int num, byte buff[]);
void readFromSPI(byte address, int num, byte buff[]);
void setRegisterBit(byte regAdress, int bitPos, bool state);
bool getRegisterBit(byte regAdress, int bitPos);
byte _buff[6] ; // 6 Bytes Buffer
int _CS = 10;
bool I2C = true;
unsigned long SPIfreq = 5000000;
I believe that the library for the redboard needs to be modified to read the output registers 0x32-0x37 as 16 bit twos compliment. I am new to this programming environment so any help is appreciated.
Thanks - Jerry
I suspect from the Sparkfun board notes (https://www.sparkfun.com/products/14812) that the problem is that the Redboard Turbo is a 32-bit processor, with a 32-bit int instead of a 16-bit int. On such a processor, all 16 bit values stored in an int are positive.
To test my theory, run the following Sketch on your Redboard Turbo:
void setup() {
Serial.begin(9600);
while (!Serial) {}
Serial.print("sizeof(int) = ");
Serial.println(sizeof(int));
}
void loop() {
}
On my Arduino Uno - a 16-bit environment - the output says that an int is two bytes (16 bits)
sizeof(int) = 2
If your Redboard Turbo instead prints
sizeof(int) = 4
then its int is 4 bytes (32 bits).
I suspect that the library wasn't written for 32-bit processors, and may show several problems on the Redboard Turbo. To fix the particular readAccel() function, rewrite it to sign-extend the 16-bit number to 32 bits:
int16_t i16; // the 16-bit result, signed.
i16 = (int16_t) ((((uint16_t)_buff[1]) << 8) | _buff[0]);
*x = (int) i16;
i16 = (int16_t) ((((uint16_t)_buff[3]) << 8) | _buff[2]);
*y = (int) i16;
i16 = (int16_t) ((((uint16_t)_buff[5]) << 8) | _buff[4]);
*z = (int) i16;
By the way, in the above rewrite of readAccel() I've used uint16_t to make sure the byte shifting happens on an unsigned value, because left-shifting a signed number can produce unexpected results on some processors.

Realtime sending PWM values using 433Mhz transmitter

I have tried to create wireless PWM transmission using 433Mhz transmitter modules. I found this library for transmiting https://github.com/zeitgeist87/RFTransmitter and this library for reading PWM values on some pin https://github.com/xkam1x/Arduino-PWM-Reader.
I wrote code for sending PWM values:
#include "PWM.hpp"
#include <RFTransmitter.h>
#define NODE_ID 1
#define OUTPUT_PIN 11
RFTransmitter transmitter(OUTPUT_PIN, NODE_ID);
PWM my_pwm(2);
// the setup function runs once when you press reset or power the board
void setup() {
my_pwm.begin(true);
}
// the loop function runs over and over again forever
void loop() {
int pwmValue = my_pwm.getValue();
char stringValue[4];
itoa(pwmValue, stringValue, 10);
transmitter.send(stringValue, strlen(stringValue) + 1);
}
And similar code for receiving
#include <Servo.h>
#include <PinChangeInterruptHandler.h>
#include <RFReceiver.h>
int PWM_out_pin = 9;
Servo servo;
// Listen on digital pin 2
RFReceiver receiver(2);
void setup() {
servo.attach(PWM_out_pin);
receiver.begin();
}
void loop() {
char msg[MAX_PACKAGE_SIZE];
byte senderId = 0;
byte packageId = 0;
byte len = receiver.recvPackage((byte *)msg, &senderId, &packageId);
String *stringObject = new String(msg);
servo.writeMicroseconds(stringObject->toInt());
}
It works, but it has few problems.
First is that is not optimal. I transforming all to string. How can I send int values from PWM directly?
Second problem is that it has about 1 sec delay. Does it possible make it faster? I need it for realtime controlling servo.
Thanks.
How can I send int values from PWM directly?
transmitter.send((char*)pwmValue, sizeof(int));
Then on the receive side, you don't need to convert the data to a string.
servo.writeMicroseconds((int) *msg);
(int) and (char*) are C-style typecasts. Essentially telling the compiler that you want the data to be interpreted as a different variable type.
WARNING: Be careful with the "new" keyword, you are dynamically allocating memory. Rule of thumb in C/C++: Wherever you use the "new" keyword there should be a corresponding "delete" call that cleans up the memory.
In terms of making it faster, your C/C++ code here is not the limiting factor causing the 1 sec latency from command to action. Most likely there is a parameter in your RF transmitter transmit/receive stack that needs to be tweaked. Before sending PWM values, I would benchmark your latency of sending and printing out a simple string.

uint32_t as Bit value to control outputs (relays)

i have 25 relays which has min 15 different configurations, which have to be stored in a "array" or something simple...i have to switch those relays on/off (HiGH/LOW).
to use as less memory as possible i want to do it with a "trick" using bit's like:
char two = B1011011;
int mask = 1;
for(int i=0; i<7; i++){
if((mask & two) == 0) digitalWrite(pins[i], LOW); else
digitalWrite(pins[i], HIGH);
mask = mask << 1;
}
but char has only 8 bits and I NEED min 25 bits...
so now it the question NR.1, can i use uint32_t just in the same way as char just with 32 bits's? or something else?
uint32_t BIG1 = B10110110111011011111101101101
uint32_t BIG2 = B10110110111011011011101101101
uint32_t BIG3 = B10110110111111011011101101101
...
uint32_t BIG = B10110110111011011011101101101;//B... and 31 0s and 1s
uint32_t mask = 1;//????? not right???
for(int i=0; i<31; i++){
if((mask & two) == 0) digitalWrite(pins[i], LOW); else
digitalWrite(pins[i], HIGH);
mask = mask << 1;
};
what would be the mask then?
or is there a better/easyer/faster way to set OUTPUTS to the needed value?
Thank you in davance!
As I already told you in the other thread, the easiest and fastest way to do this is to deal with PORTS rather than individual pins.
For example, on the arduino UNO pins 0..7 map to port D pins 0..7, so when you do something like
uint8_t the_value_i_want = 0b01001000;
PORTD = the_value_i_want;
you write the pins 0..7 in a single instruction. Now, again with the uno, the complete mapping is
PORTD maps to Arduino digital pins 0 to 7
PORTB maps to Arduino digital pins 8 to 13. The two high bits (6 & 7) map to the crystal pins and are not usable
PORTC maps to Arduino analog pins 0 to 5. Bit 6 is the reset pin, so it's not usable, while bit 7 does not exist.
So things are a bit more complicated for the other ports. Well, the easiest way to handle this is making a function to mask the relevant bits. Just note that the masking is the same for port B and C, but this is just a coincidence.
#define PORT_B_C_MASK = 0x3F;
void write_with_mask(volatile uint8_t *p_register, uint8_t mask, uint8_t value)
{
*register = (*register | (value & mask)) & (value | ~mask);
}
Now you can write easily the instructions to write the value you want on the port. For instance, if you want to turn on pins 3, 6, 8 and 10, you just have to provide two values (one for port D, i.e pins 0..7, and one for port B, pins 8..13):
uint8_t the_value_i_want_8_13 = 0b000101;
uint8_t the_value_i_want_0_7 = 0b01001000;
write_with_mask(&PORTB,PORT_B_C_MASK,the_value_i_want_8_13);
PORTD = the_value_i_want_0_7;
Now, if you want to make a const matrix with all the possible values (again, this applies for the UNO only), you can just make a three-columns uint8_t matrix. Something like
int allvalues[][3] = { {0b001000, 0b001010, 0b00000001},
...};
In this case, with the first configuration (the reported one) pins A3, 0, 9, 11 will be turned on, the others will be off.
A possible function to apply this is
void apply_configuration(uint8_t index)
{
write_with_mask(&PORTC,PORT_B_C_MASK,allvalues[index][0]);
write_with_mask(&PORTB,PORT_B_C_MASK,allvalues[index][1]);
PORTD = allvalues[index][2];
}
This way you just have to provide the index for the configuration (the row) you want to apply.
If, for some reasons, you want to exclude some pins (e.g. pin 0 and 1, since they are the serial interface) you just have to include it in the mask. For instance:
#define PORT_B_MASK = 0x3F;
#define PORT_C_MASK = 0x0F;
#define PORT_D_MASK = 0xFC;
void apply_configuration(uint8_t index)
{
write_with_mask(&PORTC,PORT_C_MASK,allvalues[index][0]);
write_with_mask(&PORTB,PORT_B_MASK,allvalues[index][1]);
write_with_mask(&PORTD,PORT_D_MASK,allvalues[index][2]);
}
This way I excluded pins 0 and 1 (serial interface) and pins A4 and A5 (I2C interface).
Just one remark: I used the UNO as example, but you can use any board. Just look at the pin mapping to understand what is the association between ports and arduino pins.

Divide two integers in Arduino

I am trying to divide two integer values and store as a float.
void setup()
{
lcd.begin(16, 2);
int l1 = 5;
int l2 = 15;
float test = 0;
test = (float)l1 / (float)l2;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(test);
}
For some reason that I expect is fairly obvious I can't seem to store and display the correct value. 'test' variable is always set to 0.
How do I cast the integer values?
It must be your LCD print routine, and thus the casts you have used are correct.
I tried it out on an Arduino using serial printing instead of an LCD. The expected result appears in the serial monitor (started by menu Tools -> Serial Monitor) for the complete code example below:
Start...
5
15
0.33
0.33333334922790
The last result line confirms it is a 4 byte float with 7-8 significant digits.
Complete code example
/********************************************************************************
* Test out for Stack Overflow question "Divide two integers in Arduino", *
* <http://stackoverflow.com/questions/13792302/divide-two-integers-in-arduino> *
* *
********************************************************************************/
// The setup routine runs once when you press reset:
void setup() {
// Initialize serial communication at 9600 bits per second:
Serial.begin(9600);
//The question part, modified for serial print instead of LCD.
{
int l1 = 5;
int l2 = 15;
float test = 0;
test = (float)l1 / (float)l2;
Serial.println("Start...");
Serial.println("");
Serial.println(l1);
Serial.println(l2);
Serial.println(test);
Serial.println(test, 14);
}
} //setup()
void loop()
{
}
lcd.print doesn't know how to print a float, so you end up printing the integer instead.