Stacking of data, extracting of value, pushing stack down - arduino

I might have missed a post for this question or searched the wrong question online so if there is something that answers this question exactly, sorry please link :)
Question: I'm trying to create a array to store a few integers in order,
data(1)
data(2)
data(3)
data(4)
data(5)
with the array complete, the program finds a average of the integers and then moves the stack up or deletes the oldest (data1) entry and moves the entire thing up by one, so it starts:
data(2)
""
data(6)
and this continues over in a loop until the software is terminated.

A stack is a LIFO data structure. It looks like you want to use a queue, which is a FIFO data structure. This can be accomplished using a circular buffer. This allows us to use a simple array. An example of the behavior you described in the question can be found in the following code example.
uint8_t qhead;
uint8_t qtail;
uint8_t qsize;
const uint8_t qcapacity = 5;
uint8_t qdata[qcapacity];
void queue_enqueue(const uint8_t data)
{
// Check to make sure that we do not overflow
if (qsize + 1 > qcapacity)
{
return;
}
qdata[qhead] = data;
// Calculate the new head
qhead = (qhead + 1) % qcapacity;
qsize++;
}
uint16_t queue_dequeue(void)
{
// Make sure there is something to dequeue
if (qsize == 0)
{
return 0xFFFFFFFF;
}
uint8_t result = qdata[qtail];
// Calculate the new tail
qtail = (qtail + 1) % qcapacity;
qsize--;
return result;
}
void setup()
{
qhead = 0;
qtail = 0;
qsize = 0;
}
void loop()
{
uint8_t data = /* Input source here */;
/* Need to fill the queue with qcapacity items first */
if (qsize < qcapacity)
{
queue_enqueue(data);
}
else
{
/* Calculate the average */
uint16_t average = 0;
for (uint8_t i = 0; i < qsize; i += 1)
{
average += qdata[i];
}
average = average / qsize;
/* Remove the old element */
queue_dequeue();
/* Add the new element */
queue_enqueue(data);
}
}

Related

Receiving a string through UART in STM32F4

I've written this code to receive a series of char variable through USART6 and have them stored in a string. But the problem is first received value is just a junk! Any help would be appreciated in advance.
while(1)
{
//memset(RxBuffer, 0, sizeof(RxBuffer));
i = 0;
requestRead(&dt, 1);
RxBuffer[i++] = dt;
while (i < 11)
{
requestRead(&dt, 1);
RxBuffer[i++] = dt;
HAL_Delay(5);
}
function prototype
static void requestRead(char *buffer, uint16_t length)
{
while (HAL_UART_Receive_IT(&huart6, buffer, length) != HAL_OK)
HAL_Delay(10);
}
First of all, the HAL_Delay seems to be redundant. Is there any particular reason for it?
The HAL_UART_Receive_IT function is used for non-blocking mode. What you have written seems to be more like blocking mode, which uses the HAL_UART_Receive function.
Also, I belive you need something like this:
Somewhere in the main:
// global variables
volatile uint8_t Rx_byte;
volatile uint8_t Rx_data[10];
volatile uint8_t Rx_indx = 0;
HAL_UART_Receive_IT(&huart1, &Rx_byte, 1);
And then the callback function:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == UART1) { // Current UART
Rx_data[Rx_indx++] = Rx_byte; // Add data to Rx_Buffer
}
HAL_UART_Receive_IT(&huart1, &Rx_byte, 1);
}
The idea is to receive always only one byte and save it into an array. Then somewhere check the number of received bytes or some pattern check, etc and then process the received frame.
On the other side, if the number of bytes is always same, you can change the "HAL_UART_Receive_IT" function and set the correct bytes count.

Trying to extract longitude and latitude from gps using arduino and neo 6m module but the loop goes up to infinity

I'm new to arduino and trying to extract gps coordinate using neo 6m module using arduino but the loop is running till infinity. Can you please help me why it is not breaking.
void gpsEvent()
{
gpsString = "";
while (1)
{
while (gps.available() > 0) //Serial incoming data from GPS
{
char inChar = (char)gps.read();
gpsString += inChar;//store incoming data from GPS to temparary string str[]
i++;
// Serial.print(inChar);
if (i < 7)
{
if (gpsString[i-1] != test[i-1]) //check for right string
{
i = 0;
gpsString = "";
}
}
if (inChar == '\r')
{
if (i > 60)
{
gps_status = 1;
break;
}
else
{
i = 0;
}
}
}
if (gps_status)
break;
}
}
void get_gps()
{
gps_status = 0;
int x = 0;
while (gps_status == 0)
{
gpsEvent();
int str_lenth = i;
coordinate2dec();
i = 0;
x = 0;
str_lenth = 0;
}
}
I have called get_gps(); in the void setup() loop to initialize the system but the gpsEvent function which is used to extract the correct string from data is running till infinite can you pls help. The reference of the code is from https://circuitdigest.com/microcontroller-projects/arduino-based-accident-alert-system-using-gps-gsm-accelerometer
but have made few changes of my own but not in the programming for the gps module.
I think one of the errors is gpsString += inChar;.
This is not Python. You are adding the value of a character to a string pointer.
You should create a buffer with a maximum length, insert a char and check buffer overflow.
Also i seems not be defined. And in C is very bad practice to use global variables as you are doing. Keep one i in the function. Check again the string length.
In general, it seems you are using a language you do not know enough to write simple programs (string manipulation is basic on C). Either learn better C or look for a python implementation (or just link) of the gps library.

Error in Turtle recursion

I'm attempting to use Turtle Graphics to make a fractal via recursion, but for some reason my code seems to not return the Turtle back to the origin.
My code is as follows
public static void sun(Turtle t, double radius) {
for ( int i = 0; i < 360; i++ ) {
t.forward( radius * .0174 );
t.left( 1 );
}
t.penup();
t.left(90);
t.forward(radius);
//t.fill();
t.pendown();
for (int i = 0; i < 8; i++) {
t.forward(2*radius);
t.backward(2*radius);
t.left(45);
}
t.penup();
t.backward(radius);
t.right(90);
t.pendown();
}
public static void fractalSun(Turtle t, double r, int level) {
int color;
if (level == 0) {
t.color(255, 0, 0);
sun(t, r);
}
else {
sun(t, r);
t.left(90);
t.forward(r);
t.right(90);
t.forward(r * 2);
t.right(90);
fractalSun(t, r/4, level -1);
t.left(90);
t.backward(r * 2);
}
}
The code compiles successfully, but produces this image:
Screenshot
My goal would be for the turtle to return to the center of each 'sun' but something isn't working.
Although the sun() method returns the turtle to where it started, the fractalSun() method leaves the turtle to the center of the figure. So whether fractalSun() calls itself or sun() it has to make adjustments. Here's an update fix with fewer changes (mostly deletions):
Change this final block of code in sun():
t.penup();
t.backward(radius);
t.right(90);
t.pendown();
to be simply one statement:
// t.penup();
// t.backward(radius);
t.right(90);
// t.pendown();
Drop three lines of code from fractalSun() and change the arguments to the final function call:
public static void fractalSun(Turtle t, double r, int level) {
if (level == 0) {
t.color(255, 0, 0);
sun(t, r);
} else {
sun(t, r);
// t.left(90);
// t.forward(r);
// t.right(90);
t.forward(r * 2);
t.right(90);
fractalSun(t, r / 4, level - 1);
t.left(90);
t.backward(r * 2 + r / 4); // added a term to the equation
}
}
OUTPUT
Note: I simulated this using Python turtle so you may need to tweak my Java code if it's amiss.
Your 8-spoke loop leaves the pen at the center of the figure after each spoke. At the end of the loop, starting at the center, you execute this sequence:
t.penup();
t.backward(radius);
t.right(90);
t.pendown();
In particular, you back up one radius; I think that's where you're getting off your intended point. Drop that line, double-check your desired direction, and I think you'll be okay.

Game of Life Processing

import processing.core.PApplet;
public class gl extends PApplet {
static int neighborCount;
static int screenRows;
int tNC; // Temporary Neighbor Count
int newState;
int columns = 960;
int rows = 477;
int[][] cells = new int[columns][rows];
int[][] newGen = new int[columns][rows];
public static void main(String[] args) {
PApplet.main("gl");
}
public void settings() {
size(1920, 955);
}
public void setup() {
// Set background white and all of cells[][] to 0 or 1
screenRows = 0;
background(255);
for (int j = 0; j < (rows / 2); j++) {
for (int i = 0; i < (columns / 2); i++) {
cells[i][j] = (int) random(0, 2);
}
}
}
public void draw() {
// If program has finished generating this frame, reset everything and set cells[][] equal to newGen[][]
if (screenRows > (height / 2)) {
screenRows = 0;
System.out.println("End of generation reached");
background(255);
cells = newGen.clone();
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
newGen[i][j] = 0;
}
}
}
// Go through every element in cells[][], determine it's value, and display it
for (int x = 1; x < (width / 2) - 1; x++) {
for (int y = 1; y < (height / 2) - 1; y++) {
printCell(x, y);
}
}
screenRows++;
}
public void printCell(int x, int y) {
setCellState(x, y);
if (newGen[x][y] == 0) {
stroke(255);
fill(255);
} else if (newGen[x][y] == 1) {
stroke(0);
fill(0);
}
System.out.println(x + ", " + y);
rect(x, y, 2, 2);
}
public void setCellState(int x, int y) {
tNC = getNeighborCount(x, y);
neighborCount = 0;
System.out.println(tNC);
if (tNC < 2) { // If less than 2 neighbors, cell dead
newGen[x][y] = 0;
} else if (tNC > 3) { // If more than 3 neighbors, cell dead
newGen[x][y] = 0;
} else if ((tNC == 2 || tNC == 3) && cells[x][y] == 1) { // If 2 or 3 neighbors and cell is alive, do nothing (unnecessary statement but makes visualizing easier)
} else if (tNC == 3 && cells[x][y] == 0) { // If 3 neighbors and cell is dead, cell is alive
newGen[x][y] = 1;
} else if (tNC == 2 && cells[x][y] == 0) { // If 2 neighbors and cel is dead, do nothing (also unnecessary)
} else {
System.out.println("Error in setCellState(int, int);"); // In event of none of the conditions being met
}
tNC = 0; // Reset variable (probably unnecessary but might as well)
}
public int getNeighborCount(int x, int y) {
// Go through each cell adjacent or diagonal to the cell and add it's value (0 or 1) to neighborCount
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
neighborCount += cells[i + x][j + y];
}
}
// Subtract the value of the cell being evaluated from neighborCount as that is not a factor in the sum of the neighbors
neighborCount -= cells[x][y];
return neighborCount;
}
}
Pastebin
I am just going for functionality over speed, for now.
I am attempting to code Conway's Game of Life using Processing in Eclipse. The above code is dysfunctional in multiple ways:
The generation displayed appears much smaller in the window than I want to be. It only takes up a fraction of the window despite my efforts to counterbalance this by making each cell 2x2 pixels and half as many rows and columns as the window is tall and wide.
Also, the generation does not appear to update in the window after the first generation is displayed after a few seconds.
I noticed that the variable tNC is often equal to 0 when it should be equal to any number from 0 to 7.
You've got three main problems.
Problem 1: You seem to be generating the next generation as you render cells, which might be okay... but then what are you doing with the screenRows logic (the if statement in your draw() function)?
If I were you, I would split your logic up into two sections: write one function that draws your board, and another function that returns a new board based on the current one. Stop trying to calculate the next generation as you're drawing the current generation, as that's just going to give you a ton of headaches.
I also don't think your logic for switching between the arrays is correct. Which array holds the current generation, and which holds the next generation? Are you sure?
Problem 2: You seem to be switching between pixel sizes and array coordinates. For example, you're drawing each cell at its array index coordinate, but you're drawing them as 2x2 rectangles. This doesn't make a ton of sense, since you're just going to draw over top of it with the next cell anyway. Again, separate your logic: create a function that draws a cell based on the window width and height, an array position, and an array length.
Problem 3: Your print statements are killing your framerate. Print statements are notoriously slow. Your framerate is already pretty slow because of all of the calculations you're doing, but it gets even slower when you print out (960*477*2) things every single frame. This isn't really a logic error, but it makes it harder to see exactly what your program is doing.
The Solution: To fix your problems, I'd recommend refactoring your code quite a bit. If I were you, I would start over with a new program. Then:
Step 1: Separate your drawing logic from your logic for calculating the next generation. Create two functions: one for drawing, and another one that returns a new array based on the current one.
Step 2: In your drawing code, make sure you separate your array indexes and your pixel positions. Maybe write another function that takes a cell position and draws a rectangle based on the window size and the array size.
PS: Are you in the same class as this person? Are you using Daniel Shiffman's code too?

processing + bitWrite + arduino

I am working with an Arduino and Processing with the Arduino library.
I get the error "The function bitWrite(byte, int, int) does not exist.";
it seams that processing + Arduino bitWrite function are not working together.
its raised due to this line:
arduino.bitWrite(data,desiredPin,desiredState);
my goal in this project is modifying a music reactive sketch to work with shift registers.
Here is my full code:
Arduino_Shift_display
import ddf.minim.*;
import ddf.minim.analysis.*;
import processing.serial.*;
import cc.arduino.*;
int displayNum = 8;
Arduino arduino;
//Set these in the order of frequency - 0th pin is the lowest frequency,
//while the final pin is the highest frequency
int[] lastFired = new int[displayNum];
int datapin = 2;
int clockpin = 3;
int latchpin = 4;
int switchpin = 7;
byte data = 0;
//Change these to mess with the flashing rates
//Sensitivity is the shortest possible interval between beats
//minTimeOn is the minimum time an LED can be on
int sensitivity = 75;
int minTimeOn = 50;
String mode;
String source;
Minim minim;
AudioInput in;
AudioPlayer song;
BeatDetect beat;
//Used to stop flashing if the only signal on the line is random noise
boolean hasInput = false;
float tol = 0.005;
void setup(){
// shift register setup
arduino.pinMode(datapin, arduino.OUTPUT);
arduino.pinMode(clockpin, arduino.OUTPUT);
arduino.pinMode(latchpin, arduino.OUTPUT);
arduino.digitalWrite(switchpin, arduino.HIGH);
//Uncomment the mode/source pair for the desired input
//Shoutcast radio stream
//mode = "radio";
//source = "http://scfire-ntc-aa05.stream.aol.com:80/stream/1018";
//mode = "file";
//source = "/path/to/mp3";
mode = "mic";
source = "";
size(512, 200, P2D);
minim = new Minim(this);
arduino = new Arduino(this, Arduino.list()[1]);
minim = new Minim(this);
if (mode == "file" || mode == "radio"){
song = minim.loadFile(source, 2048);
song.play();
beat = new BeatDetect(song.bufferSize(), song.sampleRate());
beat.setSensitivity(sensitivity);
} else if (mode == "mic"){
in = minim.getLineIn(Minim.STEREO, 2048);
beat = new BeatDetect(in.bufferSize(), in.sampleRate());
beat.setSensitivity(sensitivity);
}
}
void shiftWrite(int desiredPin, int desiredState)
// This function lets you make the shift register outputs
// HIGH or LOW in exactly the same way that you use digitalWrite().
// Like digitalWrite(), this function takes two parameters:
// "desiredPin" is the shift register output pin
// you want to affect (0-7)
// "desiredState" is whether you want that output
// to be HIGH or LOW
// Inside the Arduino, numbers are stored as arrays of "bits",
// each of which is a single 1 or 0 value. Because a "byte" type
// is also eight bits, we'll use a byte (which we named "data"
// at the top of this sketch) to send data to the shift register.
// If a bit in the byte is "1", the output will be HIGH. If the bit
// is "0", the output will be LOW.
// To turn the individual bits in "data" on and off, we'll use
// a new Arduino commands called bitWrite(), which can make
// individual bits in a number 1 or 0.
{
// First we'll alter the global variable "data", changing the
// desired bit to 1 or 0:
arduino.bitWrite(data,desiredPin,desiredState);
// Now we'll actually send that data to the shift register.
// The shiftOut() function does all the hard work of
// manipulating the data and clock pins to move the data
// into the shift register:
arduino.shiftOut(datapin, clockpin, MSBFIRST, data);
// Once the data is in the shift register, we still need to
// make it appear at the outputs. We'll toggle the state of
// the latchPin, which will signal the shift register to "latch"
// the data to the outputs. (Latch activates on the high-to
// -low transition).
arduino.digitalWrite(latchpin, arduino.HIGH);
arduino.digitalWrite(latchpin, arduino.LOW);
}
void draw(){
if (mode == "file" || mode == "radio"){
beat.detect(song.mix);
drawWaveForm((AudioSource)song);
} else if (mode == "mic"){
beat.detect(in.mix);
drawWaveForm((AudioSource)in);
}
if (hasInput){ //hasInput is set within drawWaveForm
for (int i=0; i<displayNum-1; i++){
if ( beat.isRange( i+1, i+1, 1) ){
shiftWrite(i, 1);
lastFired[i] = millis();
} else {
if ((millis() - lastFired[i]) > minTimeOn){
shiftWrite(i, 0);
}
}
}
}
} //End draw method
//Display the input waveform
//This method sets 'hasInput' - if any sample in the signal has a value
//larger than 'tol,' there is a signal and the lights should flash.
//Otherwise, only noise is present and the lights should stay off.
void drawWaveForm(AudioSource src){
background(0);
stroke(255);
hasInput = false;
for(int i = 0; i < src.bufferSize() - 1; i++)
{
line(i, 50 + src.left.get(i)*50, i+1, 50 + src.left.get(i+1)*50);
line(i, 150 + src.right.get(i)*50, i+1, 150 + src.right.get(i+1)*50);
if (!hasInput && (abs(src.left.get(i)) > tol || abs(src.right.get(i)) > tol)){
hasInput = true;
}
}
}
void resetPins(){
for (int i=0; i<ledPins.length; i++){
arduino.digitalWrite(ledPins[i], Arduino.LOW);
}
}
void stop(){
resetPins();
if (mode == "mic"){
in.close();
}
minim.stop();
super.stop();
}
BeatListener
class BeatListener implements AudioListener
{
private BeatDetect beat;
private AudioPlayer source;
BeatListener(BeatDetect beat, AudioPlayer source)
{
this.source = source;
this.source.addListener(this);
this.beat = beat;
}
void samples(float[] samps)
{
beat.detect(source.mix);
}
void samples(float[] sampsL, float[] sampsR)
{
beat.detect(source.mix);
}
}
You can achieve the same thing using standard bitwise operators. To turn a bit on:
data |= 1 << bitNumber;
The right-hand side (1 << bitNumber) is a bit-shift operation to create a suitable bit-mask. It takes the single '1' bit and moves it left until it reaches the desired position. The bitwise-or assignment (|=) combines that new bit-mask with the existing bits in data. This turns the desired bit on, but leaves the rest untouched.
The code to turn a bit off is slightly different:
data &= ~(1 << bitNumber);
You can see the same bit-shift operation here. However, it's preceded by the unary negation operator (~). This swaps all the 1's for 0's, and all the 0's for 1's. The result is the exact opposite of the bit-mask we used before. You can't do a bitwise-or operation this time though, or else you'll turn all the other bits on. The bitwise-and assignment (&=) is used instead to combine this mask with the data variable. This ensures the desired bit is turned off, and the rest are untouched.
In your code, desiredPin is the equivalent of bitNumber.
A full explanation of how bitwise operations work can be quite lengthy. I'd recommend looking for a good tutorial online if you need more help with that.
There are also the bitSet and bitClear Arduino macros that make the code a little more readable than bit shifting and using AND and OR. The format is either bitSet(what_to_modify,bit_number) and bitClear(what_to_modify,bit_number). These translate into very efficient code and can be used to manipulate both, variables and hardware registers. So for example, if you wanted to turn on pin 13 on the Arduino UNO, you would first need to look up that Arduino pin 13 is actually pin 5 on PORTB of the Atmel atmega328 chip. So the command would be:
bitSet(PORTB,5);

Resources