Hello,
this is a question regarding the BigNumber.h Library from: Arbitrary precision (big number) library port for Arduino.
I'm currently working on a device to measure corrugated tube. I'm using an encoder on a roll for the measurement and a other roll with a motor to roll up the tube.
The measurement is allredy to a certen degree precise but it would be nice if it could get better.
For that i wanted to make the floats more precise.
The Problem is that I get an overflow by approx. 5000mm for the var. Lang (meaning it jumps to approx. -5000mm).
I tryed to lower the BigNumber Scale but even with a Scale of 1 i get the same overflow.
Is there a way for that not to happen?
I'm currently useing an Arduino nano and the code below (the code is quiet long so i had to shorten it due to the char. limit).
I know the Arduino nano isn't the best for this job but it is what I currently have and as far as I understand the Library it should be possible to work.
Thanks for the help in advance
#include <LiquidCrystal.h>
#include <Keypad.h>
#include "BigNumber.h"
// Definition der Große des LCD Displays
#define LCD_ROWS 4
#define LCD_COLS 16
//Definition des Keypads
const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {19, 18, 17, 16}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {15, 14, 12}; //connect to the column pinouts of the keypad
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
const int rs = 6, en = 7, d4 = 8, d5 = 9, d6 = 10, d7 = 11; //dec der LCD Konstanten
LiquidCrystal lcd(rs, 255, en, d4, d5, d6, d7); //definierng der LCD beschaltung
//Var für Lichtschranke
int Anschlag;
int sp;
int LS = A6;
int Sp = A7; //Lichtschranke für Startposition
//Var für Encoder
static int pinA = 2;
static int pinB = 3;
volatile byte aFlag = 0;
volatile byte bFlag = 0;
volatile float encoderPos = 0;
volatile float oldEncPos = 0;
volatile byte reading = 0;
int s, d = 255;
bool Start = LOW;
int ein[5] = {0, 0, 0, 0, 0};
//Menü Var
int p = 1;
bool Man;
int I = 0;
//State Var
int State = 1;
bool M = HIGH, G = HIGH, F = LOW, A = LOW, B = LOW, C = LOW, D = LOW, SollR = LOW, H = LOW;
void setup() {
Serial.begin(9600);
//ini encoder und Interrupt
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
attachInterrupt(0, PinA, RISING);
attachInterrupt(1, PinB, RISING);
//ini PinModes
pinMode(5, OUTPUT);
pinMode(4, INPUT_PULLUP);
//enable Interrupts
interrupts();
//ini LCD
lcd.begin(16, 4);
lcd.setCursor(0, 0);
lcd.display();
lcd.print("FAFNIR");
do {
sp = analogRead(Sp);
analogWrite(5, 255);
Serial.println(sp);
}
while (sp < 100);
analogWrite(5, 0);
}
void printBignum (BigNumber n)
{
char * s = n.toString ();
lcd.print (s);
//Serial.println (s);
free (s);
}
//Start Menü
void SartMenu() {
...
}
void StShMenu() {
...
}
void ManMenu() {
...
}
void Beenden() {
...
}
void Warten() {
...
}
void readKeypadEnd() {
...
}
void readKeypadManMenu()
{
...
}
void readKeypadStShMenu()
{
...
}
void readKeypadStartMenu()
{
...
}
void readKeypadGewichtMenu()
{
...
}
void Kolibri() {
...
}
//Interrupts
void PinA() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && aFlag) {
encoderPos --;
bFlag = 0;
aFlag = 0;
}
else if (reading == B00000100) bFlag = 1;
sei();
}
void PinB() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && bFlag) {
encoderPos ++;
bFlag = 0;
aFlag = 0;
}
else if (reading == B00001000) aFlag = 1;
sei();
}
void Messung() {
if (SollR == LOW) {
if (H == LOW) {
if (M == HIGH) {
if (G == HIGH) {
Soll = ein[4] + ein[3] * 10 + ein[2] * 100 + ein[1] * 1000 + ein[0] * 10000;
Soll = Soll - 1057.6;
}
else {
Soll = ein[4] + ein[3] * 10 + ein[2] * 100 + ein[1] * 1000 + ein[0] * 10000;
Soll = Soll - 1015.6;
}
}
else if (M == LOW) {
if (G == HIGH) {
Soll = ein[4] + ein[3] * 10 + ein[2] * 100 + ein[1] * 1000 + ein[0] * 10000;
Soll = Soll - 557.6;
}
else {
Soll = ein[4] + ein[3] * 10 + ein[2] * 100 + ein[1] * 1000 + ein[0] * 10000;
Soll = Soll - 515.6;
}
}
}
else if (H == HIGH) {
Soll = ein[4] + ein[3] * 10 + ein[2] * 100 + ein[1] * 1000 + ein[0] * 10000;
}
SollR = HIGH;
}
Anschlag = analogRead(LS);
if (Man == HIGH && Anschlag < 100) {
lcd.clear();
lcd.print("Bereit!");
delay(100);
}
if (Anschlag > 100) {
BigNumber::begin (15); // initialize library
BigNumber Lang;
BigNumber U("0.150480225537958");
BigNumber u("0.340296593401490");
if (oldEncPos != encoderPos) {
Lang = (BigNumber(encoderPos) * U ) - u; //Encoder 1024 Tic/U
lcd.clear();
lcd.print("L");
lcd.print("\xE1");
lcd.print("nge in mm:");
lcd.setCursor(0, 1);
//lcd.print(Lang);
printBignum (Lang);
if (Man == LOW) {
lcd.setCursor(0, 2);
lcd.print("Soll:");
lcd.print(Soll);
lcd.setCursor(0, 3);
lcd.print("Roh:");
lcd.print(encoderPos);
}
else if (Man == HIGH) {
lcd.setCursor(0, 2);
lcd.print("Encoder Rohwert:");
lcd.setCursor(0, 3);
lcd.print(encoderPos);
}
delay(100);
oldEncPos = encoderPos;
}
BigNumber::finish ();
char key1 = keypad.getKey();
if (key1 == '#' || F == HIGH) {
F = HIGH;
if (Lang < Soll && Start == LOW) {
for (int s = 100; s <= 255; s++) {
analogWrite(5, s);
delay(50);
Start = HIGH;
}
Start = HIGH;
}
else if (Lang >= Soll - 200) {
d = Soll - Lang;
s = map(d, 0, 200, 80, 255);
analogWrite(5, s);
}
if (d <= 80) {
if (Lang < Soll) {
analogWrite(5, 80);
}
else {
analogWrite(5, 0);
Start = LOW;
F = LOW;
}
}
}
if (key1 == '*' && F == LOW) {
State = 6;
}
}
else {
encoderPos = 0;
}
}
void loop() {
Man = digitalRead(4);
if (Man == HIGH) {
State = 5;
}
switch (State) {
case 1:
SollR = LOW;
if (A == LOW) {
SartMenu();
A = HIGH;
}
B = LOW;
C = LOW;
H = LOW;
D = LOW;
readKeypadStartMenu();
break;
case 2:
if (B == LOW) {
StShMenu();
B = HIGH;
}
M = HIGH;
A = LOW;
if (C == HIGH) {
readKeypadStShMenu();
lcd.cursor();
}
else {
readKeypadGewichtMenu();
}
break;
case 3:
if (B == LOW) {
StShMenu();
B = HIGH;
}
M = LOW;
A = LOW;
if (C == HIGH) {
readKeypadStShMenu();
lcd.cursor();
}
else {
readKeypadGewichtMenu();
}
break;
case 4:
if (D == LOW) {
ManMenu();
D = HIGH;
}
A = LOW;
H = HIGH;
readKeypadManMenu();
lcd.cursor();
break;
case 5:
lcd.noCursor();
Messung();
A = LOW;
B = LOW;
C = LOW;
D = LOW;
break;
case 6:
Beenden();
readKeypadEnd();
break;
case 7:
Warten();
do {
sp = analogRead(Sp);
analogWrite(5, 255);
}
while (sp < 100);
analogWrite(5, 0);
Soll = 0;
d = 255;
State = 1;
break;
case 8:
Kolibri();
break;
default:
lcd.setCursor(0, 2);
lcd.print(" ERORR!");
break;
}
}