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.
Related
The code example is used to create a binary counter using a row of LEDs. I was checking out an online tutorial that issued this as a challenge. My goal was to do this in a way that is scalable.
The below code is functioning, but I have an issue. Within the setup function, I call the Serial.begin function which I was using for logging while writing the code. As it is, the code loops through from 0 to 16, flashing the correct corresponding LED.
When I remove the Serial.begin line, the loop breaks, but at a weird point. It goes all the way through to 16 once (ie all 4 LEDs lit) and then it loops back around, and then gets stuck flashing just the one LED (indicating 1). The puzzling thing to me is obviously since the loop starts at 0, it's actually going through to the second iteration of the loop when it fails.
I'm not otherwise using any other Serial functions and since it works with Serial.begin, I feel like it's mathematically sound. It's leading me to think this is something Arduino specific and I'd really like to understand what's happening here to produce the different results.
I'm also new to C++ and Arduino in general, so general advice or feedback is also appreciated!
/*
* The following code runs an Arduino powering 4 LEDs counting in binary
* Mission was to do this dynamically using for-loops, so that it is scalable for adding say, more LEDs
* To add an LED, all one needs to do is update the variable 'bits', increase the size of the 'ledArray' and 'myArray' and assign Arduino pins to the new LEDs
*/
// using Arduino pins 3, 5, 6 & 9. While I'm using PWM pins, this code uses digital write and there's no need to stick to these for the purpose of this code
int led1 = 3;
int led2 = 5;
int led3 = 6;
int led4 = 9;
int bits = 4; // the number of bits AKA the number of LEDs in the circuit
int del = 350; // the interval for each flash
int topNumber = pow(2,bits); // define the decimal number that can be counted to on a given set.
int ledArray[4] = {led1, led2, led3, led4}; // this array is made up of the Arduino pins. The array size should be the same as the number of bits
int myArray[4] = {0}; // this array is the array that creates the binary string. The array size should be the same as the number of bits
void setup() {
Serial.begin(9600); // Getting some odd behaviour with this :/ originally here for troubleshooting
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}
void loop() {
// the following for-loop iterates each number in the set from 0 to the ceiling (topNumber)
for (int n = 0; n <= topNumber; n++) {
int tempValue = n; // set a temporary variable for n - we're going to manipulate n to format our binary, but we want to come back to this value before this loop concludes to increment on it
// the following for-loop builds an array to present the binary string eg 1,0,0,1 for 1001
for (int i = 0; n > 0; i++) {
myArray[i] = n % 2;
n /= 2;
}
// the following for-loop matches the leds in the ledArray with the binary array and sets the voltage high as required
for (int i = 0; i <= bits; i++) {
if(myArray[i] == 1) {
digitalWrite(ledArray[i], HIGH);
} else {
}
}
delay(del);
// the following for-loop iterates through the ledArray and switches them all off after completion
for (int i = 0; i <= bits; i++) {
digitalWrite(ledArray[i],LOW);
}
n = tempValue; // return n to its original value so that the for-loop will iterate as intended
}
}
n <= topNumber should be n < topNumber.
Here's what the as-written code does:
topNumber = 2 raised to the 4th power, that is 16. 16 in binary is 10000; note that that uses 5 bits rather than 4. When the loop()'s for() loop reaches n = 16, it writes into myArray[4], which doesn't exist.
Because C and C++ don't protect against out of bounds array accesses, that loop writes a value into some other place in memory. My guess is that adding or removing the Serial.begin() line likely rearranges memory a little, which changes the effect of writing into that non-existent myArray[4].
One C language thing you probably know: arrays declare the number of items in the array; not the index of the last member of the array. So myArray[4] declares an array with myArray[0], myArray[1], myArray[2], and myArray[3]. There is no myArray[4].
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.
Can someone explain how to modify this program to "ReadAnalogVoltage" once every 60 seconds, forever.
Right now it reads the voltage every millisecond (I think), forever.
Too much information is being generated.
Any suggestions would be appreciated.
Rob.
> /*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints
the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside
pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(voltage);
}
There are several ways to lower the sampling rate. Place a counter inside your loop and only print when the counter reaches a certain value. Be sure to reset the value after printing.
int counter = 0;
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
if(counter >= 1000000){
Serial.println(voltage);
counter = 0;
}
}
The best way to solve this is with an time interrupt. The actual mechanics of setting the interrupt will depend on what hardware you are using.
Can someone please help me with code? I have a 24 teeth trigger wheel. Every tooth is registered by hall sensor and I need that Arduino simulate 36 pulse output of that corresponding 24 pulse input.
Here is my code with delayMicroseconds, but I can`t use delayMicroseconds, because Arduino doesn't understand bigger than 16k micros delay.
const int hall = 2; // hall sensor
const int ledPin = 13; // the pin that the LED is attached to
// Variables will change:
int teethCounter = 0;
int hallState = 0;
int lasthallState = 0;
long cycles=0;
boolean cycle = false;
unsigned long microsStart = 0;
unsigned long microsStop = 0;
unsigned long usElapsed = 0;
unsigned long usElapsedUp = 0;
unsigned long usInterval;
void setup() {
// initialize the button pin as a input:
pinMode(hall, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
hallState = digitalRead(hall);
if(cycle==true){
microsStart=micros();
}
if(cycle==true){
usInterval = usElapsedUp/72;
for (int i=0; i <= 36; i++){
digitalWrite(13,HIGH);
delayMicroseconds(usInterval);
digitalWrite(13,LOW);
delayMicroseconds(usInterval);
cycle = false;
}
}
// compare the hallState to its previous state
if (hallState != lasthallState) {
// if the state has changed, increment the counter
if (hallState == HIGH) {
teethCounter++;
if(teethCounter==24){
cycle = true;
cycles++;
teethCounter=0;
usElapsedUp = usElapsed;
}
Serial.print("Tooth count: ");
Serial.print(teethCounter);
Serial.print(" Cycles: ");
Serial.print(cycles);
Serial.print(" Time: ");
Serial.print(usElapsedUp);
Serial.print(" Interval: ");
Serial.println(usInterval);
}
microsStop=micros();
usElapsed=microsStop-microsStart;
}
// save the current state as the last state,
//for next time through the loop
lasthallState = hallState;
}
How can I calculate and from where can I take trigger points?
If(event happens==true){
digitalWrite(13,HIGH);
}
If(event happens==false){
digitalWrite(13,LOW);
}
If it helps to understand here is a block diagram
As long as you understand that you will never be able get 36 pulses per turn accuracy with 24 pulse/turn, you can do this, which is a common trick derived from the Bresenham algorithm. This solution assumes you are concerned about the position.
Now, this will generate pulses in real-time, as opposed to your code, which generates pulses in a blocking manner, I don't think losing pulses was your original intent.
This code will not generate pulses uniformly, 1 out of 3 readings will generate 2 pulses.
Another way would be to calculate the average speed and program a hardware timer to simulate the 36 pulses per turn, using interrupts, but going that route would likely (invariably, in my experience) end up in total loss of sync between the actual position of the wheel and what your corrected tick count reports. There are also strict speed ranges that you have to respect if going that route, also this will introduce severe latency issues to your application.
Change the increment value to 36, and the whole turn count to 24/36.
Change the step detection to a threshold of 24.
I'm trying to understand why you want to do this 36/24 thing, and can't.
So, your mileage may vary.
// compare the hall State to its previous state
// to declared outside of loop()
// int smallCounter;
// PULSE_WIDTH as small positive pulse with in us
//
if (hallState != lasthallState) {
// if the state has changed, increment the counter
smallCounter += ((hallState == HIGH) ? 36 : 0);
// ... I'm assuming that the serial prints you had here were just here for debugging.
lasthallState = hallState;
}
//
// reporting for each step below
//
if (smallCounter >= 24)
{
smallCounter -= 24;
if (++teethCounter >= 36) {
cycle = true;
cycles++;
teethCounter=0;
usElapsedUp = usElapsed;
}
digitalWrite(13,HIGH);
delayMicroseconds(PULSE_WIDTH);
digitalWrite(13,LOW);
delayMicroseconds(PULSE_WIDTH); // this is probably not needed.
}
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.