How to print out a set of variables in a for loop - arduino

I'm writing a program that logs and prints digital and analog inputs. Unfortunately, the arduino is running out of memory. To make the program smaller I'm trying to print the inputs using a for loop. I've been trying to do:
for(int analog = analog0; analog <= analog9; analog ++){
Serial.println(analog);
}
When I run the arduino, it doesn't always print out all of the inputs, sometimes it prints out none, or one or two, up to around 16 inputs (I only have 10 wired up). Each time this loop runs, it prints a different amount of inputs. Any suggestions?

I don't know anything about arduino, but if analog0 is a reading of a analog value, then of course this code is not going to work. The value of analog is going to be a random ADC value! Perhaps you need to do
for(int i = 0; i<= 9; i++){
Serial.println(analogRead(i));
}

First of all your for loop is incorrectly coded.
Also, try storing the analog ints outside of loop():
int analog[10];
// etc.
loop() {
int x;
analog[0] = analogRead(analogPin0);
analog[1] = analogRead(analogPin1);
// etc. do calcs
// for a beginning programmer, this for loop is OK
for (idx = 0; idx < 10; idx++) {
serial.println(analog[idx]);
}
}

Related

Why does the IR reciver gives diffrent value everytime I try to break a for loop - when new value is recived, Arduino ide?

I am new to Arduino programming and was trying to make an IR-controlled WS2812 led strip light, everything works fine apart from when I try to stop the for-loop when my IR receiver gets a new decoded value. It does get the job done but the received values are different every time. when I tested the same controller with a simple IR receiver program everything worked fine.
switch(value){
case 16720095:
delay (200);
irrecv.resume();
for (int i = 0; i <= 182; i++) {
leds[i] = CRGB (0,0,0);
FastLED.show();
if (irrecv.decode(&results))
{
value = results.value;
Serial.println(value);
break;
}
delay(40);
}
}
}
and the serial outputs:
first time:
16720095
-1572362453
second time:
16720095
-1406992986
third time:
16720095
811035822
It looks like you need to call "irrecv.resume()" within the if (irrecv.decode(&results)) block in order to tell the driver to keep looking for signals. The second values you are getting are garbage because you are asking it to provide data it hasn't received/ prepared.

Arduino - sending large amount of data over Serial

I am trying to build a simple FLASH memory programmer (for 39SF020A) using my arduino mega. I wrote the C code and Python script to send the data over (And it all works as expected).
I need to transfer about 32k of hexadecimal data, but with my settings only 10k of data took about 4 minutes (115200 BAUD), which i found unnecessary long. Currently, i am sending over serial (from Python) my value with a terminator (i chose '$'), so for exmple '3F$'. adresses are calulated on the arduino, so no need to send them.
In my arduino code, i have
String received_string = Serial.readStringUntil('$');
and after programming every byte to teh FLASH using arduino, it sends back a '\n' to let the Python know, that it is ready to receive next byte (the python is waiting for receiving a 'line' and then continues). I am not really sure if this is a way to do it, if sending only one byte at the time is good idea and if not, how many and how do i parse them on the arduino? Is the feedback loop useful?
Thanks.
Python Code:
('file' contains all data)
for item in file[1:]:
ser.write((item + "$").encode("ascii"))
line = ser.readline()
i += 1
if i >= top:
break
elif (i % 100) == 0:
print(i)
Arduino code (just part of it)
if (Serial.available() > 0){
String received_string = Serial.readStringUntil('$');
programData(received_string.toInt(),program_adress);
program_adress++;
}
void programData(char data_in, unsigned long adress)
{
digitalWrite(OE,HIGH);
digitalWrite(CE,LOW);
writeByte(0xAA, 0x5555);
writeByte(0x55, 0x2AAA);
writeByte(0xA0, 0x5555);
writeByte(data_in, adress);
Serial.print("\n"); // Feedback for Python
delayMicroseconds(30); // Just to be on the safe side
}
void writeByte(char data_in, unsigned long adress)
{
setDataAs(OUTPUT);
digitalWrite(OE,HIGH);
digitalWrite(WE,HIGH);
setAdress(adress);
setData(data_in);
digitalWrite(WE,LOW);
delayMicroseconds(1);
digitalWrite(WE,HIGH);
}
// Sets data BUS to input or output
void setDataAs(char dir){
for (unsigned int i = 0; i < data_size ;i++) pinMode(data[i],dir);
}
// Sets data to specific values
void setData(char data_i){
setDataAs(OUTPUT);
for (int i = 0; i < data_size;i++) { digitalWrite(data[i],bitRead(data_i,i)); }
}
void setAdress(long adr){
// Set all adresses
for (int i = 0; i < adresses_size;i++)
digitalWrite(adresses[i],bitRead(adr,i));
}

Data sent through serial on arduino gets byte-shifted sometimes

I'm sending data through USART on an Arduino Due. I'm currently filling a buffer so the data gets sent just when a buffer is full.
The data I'm putting into the buffer is a lookup table of different wave shapes with 12 bits of depth (values from 0 to 4095). So I'm putting into the buffer values that are 2 bytes of depth, and the most significant byte is always 0.
My problem is that everyonce in a while a whole wave period gets shifted a byte (every value gets multiplicated by 256). The error is unpredictable: it might happen on the 2nd or 3rd period to be sent, but it happens soon. I tried slower baudrates, or adding two stopbits, but nothing fixes it. The relevant chunk of the code:
const int buflen = 2048;
int i = 0;
int j = 0;
int k = 1;
int wave = 0;
short buff[buflen];
volatile PROGMEM short sintab[3][512] = ...//there's no need to paste here the lookup tables
void setup(void){
Serial3.begin(115200, SERIAL_8N2);
}
void loop(void) {
buff[j]= sintab[wave][i];
i+= k;
j++;
if (i>511){
i-=512;
}
if (j>=buflen){
byte* bytePointer =(byte*)buff;
for (int l=0; l<=buflen; l++){
Serial3.write(bytePointer[l]);
Serial3.flush();
}
int j = =0;
}
I'm checking the received data on both a serial monitor and a python program that stores the received values and print them. I think its weird that the error never happens in the middle of a wave: a one or two waves are copied good on the buffer and then a whole value gets shifted. How could I fix this?
It looks like the issue is not in this block of code where you're writing the data out to your USART port, rather in storing the data to that array. When you have this byte offset occur, can you validate that the data in your array is as you expect it to be?
Edit:
Change
for (int l=0; l<=buflen; l++)
to
for (int l=0; l< buflen; l++)
so you enumerate over the set 0 to 511, which is 512 elements. Now you are enumerating an additional element, which is reading data from an unexpected memory location and returning whatever is there (likely the next byte of your static structure).

Calculating the average of Sensor Data (Capacitive Sensor)

So I am starting to mess around with Capacitive sensors and all because its some pretty cool stuff.
I have followed some tutorials online about how to set it up and use the CapSense library for Arduino and I just had a quick question about this code i wrote here to get the average for that data.
void loop() {
long AvrNum;
int counter = 0;
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter = 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
}
}
This is my loop statement and in the Serial it seems like its working but the numbers just look suspiciously low to me. I'm using a 10M resistor (brown, black, black, green, brown) and am touching a piece of foil that both the send and receive pins are attached to (electrical tape) and am getting numbers around about 650, give or take 30.
Basically I'm asking if this code looks right and if these numbers make sense...?
The language used in the Arduino environment is really just an unenforced subset of C++ with the main() function hidden inside the framework code supplied by the IDE. Your code is a module that will be compiled and linked to the framework. When the framework starts running it first initializes itself then your module by calling the function setup(). Once initialized, the framework enters an infinite loop, calling your modules function loop() on each iteration.
Your code is using local variables in loop() and expecting that they will hold their values from call to call. While this might happen in practice (and likely does since that part of framework's main() is probably just while(1) loop();), this is invoking the demons of Undefined Behavior. C++ does not make any promises about the value of an uninitialized variable, and even reading it can cause anything to happen. Even apparently working.
To fix this, the accumulator AvrNum and the counter must be stored somewhere other than on loop()'s stack. They could be declared static, or moved to the module outside. Outside is better IMHO, especially in the constrained Arduino environment.
You also need to clear the accumulator after you finish an average. This is the simplest form of an averaging filter, where you sum up fixed length blocks of N samples, and then use that average each Nth sample.
I believe this fragment (untested) will work for you:
long AvrNum;
int counter;
void setup() {
AvrNum = 0;
counter = 0;
}
void loop() {
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter == 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
AvrNum = 0;
}
}
I provided a setup(), although it is redundant with the C++ language's guarantee that the global variables begin life initialized to 0.
your line if (counter = 10) is invalid. It should be if (counter == 10)
The first sets counter to 10 and will (of course) evaluate to true.
The second tests for counter equal to 10 and will not evaluate to true until counter is, indeed, equal to 10.
Also, kaylum mentions the other problem, no initialization of AvrNum
This is What I ended up coming up with after spending some more time on it. After some manual calc it gets all the data.
long AvrArray [9];
for(int x = 0; x <= 10; x++){
if(x == 10){
long AvrMes = (AvrArray[0] + AvrArray[1] + AvrArray[2] + AvrArray[3] + AvrArray[4] + AvrArray[5] + AvrArray[6] + AvrArray[7] + AvrArray[8] + AvrArray[9]);
long AvrCap = AvrMes/x;
Serial.print("\t");
Serial.println(AvrCap);
x = 0;
}
AvrArray[x] = cs_4_2.capacitiveSensor(30);
Serial.println(AvrArray[x]);
delay(500);

Infra Red Arduino Custom Serial

Basically I am looking to make an serial-like system that runs communication between IR LEDs on an arduino. Below the code gets to the point having an array with a collection of 1s and 0s in it. I need to convert this 8 bit array into a single character and output it. But I don't know how to do this. Help would be appreciated.
int IR_serial_read(){
int output_val;
int current_byte[7];
int counter = 0;
IR_serial_port = digitalRead(4);
if (IR_serial_port == HIGH){
output_val =1;
}
if (IR_serial_port == LOW){
output_val =0;
}
current_byte[counter] = output_val;
counter +=1
}
This would best be done with bitwise operators, I think the or function would be of best use here as it will set a bit if the input is 1 and not change it if it is 0, could use a loop to loop through your array and set the bits.
Looking at your code, are you sure you are receiving all 8 bits? You seem to be saving 7 bits.
As you are creating a byte array solely for the purpose of using only 1s and 0s, it suggest immediately setting the bits in the same loop.
Here is the code that I suggest:
byte inputByte = 0; // Result from IR transfer. Bits are set progressively.
for (byte bit = 0; bit < 8; bit++) { // Read the IR receiver once for each bit in the byte
byte mask = digitalRead(4); // digitalRead returns 1 or 0 for HIGH and LOW
mask <<= bit; // Shift that 1 or 0 into the bit of the byte we are on
inputByte |= mask; // Set the bit of the byte depending on receive
}
This would also be put inside a loop to read all the bytes in your data stream.
It is designed for readability and can be optimised further. It reads the least significant bit first.
You can also apply the same technique to your array if you wish to keep using an array of bytes just for 1s and 0s, just replace the digitalRead with the array location (current_byte[bit]).

Resources