I am really confused on loops; I am new to C# (I have only ever worked with assembly on 16 and 32 bit micro controllers).
any way I have this code:
{
{
Console.WriteLine("Enter the first number");
Decimal iNumber1;
if (!Decimal.TryParse(Console.ReadLine(), out iNumber1)) { Console.WriteLine("Enter a number dummy"); Console.Read(); return; }
Decimal x = iNumber1;
Console.WriteLine("Enter the second number");
Decimal y = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter 1 for addition");
Console.WriteLine("Enter 2 for subtration");
Console.WriteLine("Enter 3 for multification");
Console.WriteLine("Enter 4 for divition");
int z = Convert.ToInt32(Console.ReadLine());
switch (z)
{
case 1:
Console.WriteLine(x + y);
break;
case 2:
Console.WriteLine(x - y);
break;
case 3:
Console.WriteLine(x * y);
break;
case 4:
Console.WriteLine(x / y);
break;
default:
break;
}
}
Console.ReadLine();
}
}
}
This is just a simple console app calculator; but I want to be able to loop back to the start if a number isn't entered.
This will allow you to run until Esc is pressed.
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
// your code
}
Related
In Arduino Serial I need to read those kind of lines <1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16> As fast
as possible, without blocking.
The goal is to set values of array compensation[] without delay.
In this example <1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16> Would display 1000 (as 100% have been read) But I don't get 100% but periodique losses at 96% and then 95% … So I need my code to display 1000 (for 100%) every time.
This is what I have already :
static int compensastion[64];
int passage=1;
const byte numChars = 1000;
char receivedChars[numChars];
boolean newData = false;
int score = 0;
int mal_score = 0;
void setup() {
Serial.begin(115200);
Serial.println();
}
void loop() {
read_inputs();
// get the percentage of success for this simple message from 1 to 16
Serial.print(double(double(score) / double(mal_score+score))*10000);
Serial.println();
}
void read_inputs(){
recvWithStartEndMarkers();
check();
}
// Get the full line <1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16>
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
if (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0';
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
// Parse the line in digits
void check(){
if (newData == true) {
newData = false;
int marge = 0;
passage=1;
for(int j = 0; j < numChars; j=j+1){
int my_int = -1;
char buf[4];
if(isDigit(receivedChars[j]) &&marge == 0 ){
if(!isDigit(receivedChars[j+1])){
my_int = receivedChars[j] - '0';
marge=marge+1;
}
if(isDigit(receivedChars[j+1]) && !isDigit(receivedChars[j+2]) ){
my_int = receivedChars[j] - '0';
my_int = my_int*10 + (receivedChars[j+1] - '0');
marge=marge+2;
}
if(isDigit(receivedChars[j+1]) && isDigit(receivedChars[j+2]) && !isDigit(receivedChars[j+3]) ){
my_int = receivedChars[j] - '0';
my_int = my_int*10 + (receivedChars[j+1] - '0');
my_int = my_int*10 + (receivedChars[j+2] - '0');
marge=marge+3;
}
}
if (isDigit(receivedChars[j]) && my_int != -1){
if(passage == my_int){
score=score+1;
}else{
mal_score= mal_score+1;
}
compensastion[(passage-1)*2] = my_int;
passage=passage+1;
if(passage+1 >= 16+2){
passage=1;
}
}
if(marge > 0){
marge=marge-1;
}
}
}
}
In my experience, one of the most effective ways to handle huge amounts of serial data is using Interrupts and Finite State Machines (FSM).
Please carefully read this guide by the amazing Nick Gammon. FSMs are the most versatile approach when dealing with intensive processing tasks. (Not to be confused with RTOS, though)
Regarding the serial communication, I would implement the serial reading through the serialEvent() interrupt along the lines of the following example:
char serialString[] = " "; // Empty serial string variable
bool stringFinished = false; // Flag to indicate reception of a string after terminator is reached
void setup(){
previousEncoderTime = 0;
}
void loop(){
unsigned long now = millis();
if (stringFinished){ // When the serial Port has received a command
stringFinished = false;
// Implement your logic here
}
}
void serialEvent()
{
int idx = 0;
while (Serial.available())
{
char inChar = (char)Serial.read();
if (inChar == '\n') // The reading event stops at a new line character
{
serialTail = true;
serialString[idx] = inChar;
}
if (!serialTail)
{
serialString[idx] = inChar;
idx++;
}
if (serialTail)
{
stringFinished = true;
Serial.flush();
serialTail = false;
}
}
}
Finally, try to compartmentalize all the necessary data processing in single-purpose functions. This way your code will have a proper flow and you will reduce the risk of blocking the system with heavy tasks.
EDIT: I forgot to mention that the Serial.available() is regarded as a polling method which is highly unreliable and time-consuming. Stick to interrupts and you won't have massive issues
I have made a simple program that controls a 10-LED bar graph and the speed in which the LEDs change is supposed to be controlled by a 10K POT. I am using 16F88 (and CSS Compiler/Mplab v8.91) for this simple Program, but the 10k POT is not responding to a full turn of the POT. Only toward in the Last 5% of MAX on the POT, does the speed change a few steps. From Minimum to 95% (of MAX) there is no change in the speed of output of the LEDs.
All other parts of the code with. Just need to get this POT figured out.
Thanks in Advance!
#include <16f88.h>
#device ADC=10
#device *=16
#ZERO_RAM
//////// Fuses: LP,XT,HS,EC_IO,NOWDT,WDT,NOPUT,PUT,MCLR,NOMCLR,BROWNOUT
//////// Fuses: NOBROWNOUT,LVP,NOLVP,CPD,NOCPD,WRT,NOWRT,DEBUG,NODEBUG,CCPB0
//////// Fuses: CCPB3,PROTECT,NOPROTECT,INTRC,INTRC_IO,RC,RC_IO,FCMEN
//////// Fuses: NOFCMEN,IESO,NOIESO
#fuses INTRC_IO,NOWDT,PUT, NOMCLR, PROTECT, NOBROWNOUT, NOLVP, NOWRT, NOCPD
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#byte PORTA = 0x5
#byte PORTB = 0x6
/**********************************************************************/
/* PIC interface */
/**********************************************************************/
#bit LED1 = PORTA.1 //Output
#bit LED2 = PORTA.2
#bit LED3 = PORTA.3
#bit LED4 = PORTA.4
#bit LED5 = PORTA.6
#bit LED6 = PORTA.7
#bit LED7 = PORTB.0
#bit LED8 = PORTB.1
#bit LED9 = PORTB.2
#bit LED10 = PORTB.3
#bit LED_GREEN = PORTB.4
#bit SP_OUT = PORTB.5 //Short Pulse
/**************************************************************************
* Global Variables
**************************************************************************/
int speed, state, adc0;
unsigned int16 t,t1, t2,t3, t4;
short flag, flag1,flag2;
/**************************************************************************
* Speed
**************************************************************************/
void f_speed(void) {
SET_ADC_CHANNEL(0);
delay_us(100);
adc0 = READ_ADC();
if(adc0<1) adc0=1;
if(adc0>0 && adc0<=32)
t2=2800; //280ms
if(adc0>32 && adc0<=64)
t2=2450;; //245ms
if(adc0>64 && adc0<=96)
t2=2100; //210ms
if(adc0>96 && adc0<=128)
t2=1750;
if(adc0>128 && adc0<=160)
t2=1400;
if(adc0>160 && adc0<=192)
t2=1050;
if(adc0>192 && adc0<=224)
t2=700;
if(adc0>224 && adc0<=256)
t2=350; //35ms
}
/**************************************************************************
* Mode 1 basic Scan
**************************************************************************/
void f_mode_1(void) {
// SPM_BASIC_SCAN
if(flag1){
flag1=0;
flag2=1;
t=0;
}
if(flag2){
if(t>10){
SP_OUT=1;
flag2=0;
t4=0;
}
}
switch(state){
case 1:
// PORTA = 0b00000001; // SCAN STARTS
LED1=1;
if(t3>t2){
t3=0;
state=2;
LED1=0;
}
break;
case 2:
LED2=1;
if(t3>t2){
t3=0;
state=3;
LED2=0;
}
break;
case 3:
LED3=1;
if(t3>t2){
t3=0;
state=4;
LED3=0;
}
break;
case 4:
LED4=1;
if(t3>t2){
t3=0;
state=5;
LED4=0;
}
break;
case 5:
LED5=1;
if(t3>t2){
t3=0;
state=6;
LED5=0;
}
break;
case 6:
LED6=1;
if(t3>t2){
t3=0;
state=7;
LED6=0;
}
break;
case 7:
LED7=1;
if(t3>t2){
t3=0;
state=8;
LED7=0;
}
break;
case 8:
LED8=1;
if(t3>t2){
t3=0;
state=9;
LED8=0;
}
break;
case 9:
LED9=1;
if(t3>t2){
t3=0;
state=10;
LED9=0;
}
break;
case 10:
LED10=1;
if(t3>t2){
t3=0;
state=11;
LED10=0;
}
break;
case 11:
LED9=1;
if(t3>t2){
t3=0;
state=12;
LED9=0;
}
break;
case 12:
LED8=1;
if(t3>t2){
t3=0;
state=13;
LED8=0;
}
break;
case 13:
LED7=1;
if(t3>t2){
t3=0;
state=14;
LED7=0;
}
break;
case 14:
LED6=1;
if(t3>t2){
t3=0;
state=15;
LED6=0;
}
break;
case 15:
LED5=1;
if(t3>t2){
t3=0;
state=16;
LED5=0;
}
break;
case 16:
LED4=1;
if(t3>t2){
t3=0;
state=17;
LED4=0;
}
break;
case 17:
LED3=1;
if(t3>t2){
t3=0;
state=18;
LED3=0;
}
break;
case 18:
LED2=1;
if(t3>t2){
t3=0;
state=1;
LED2=0;
}
break;
}
}
/**************************************************************************
* Clear_LED
**************************************************************************/
void Clear_LED(void){
LED1=0;
LED2=0;
LED3=0;
LED4=0;
LED5=0;
LED6=0;
LED7=0;
LED8=0;
LED9=0;
LED10=0;
}
/*************************************************************************
* timer0 Interrupts 100useg
**************************************************************************/
#INT_TIMER0
void TIMER0_isr()
{
set_timer0(156);
t3++; // Speed timer
t4++; //Short pulse timer
if(t4>5000) {
t4=0; //500ms
SP_OUT = 0;
}
}
/*************************************************************************
* timer1 Interrupts 100ms
**************************************************************************/
#INT_TIMER1
void TIMER1_isr()
{
set_timer1(53036);
t++;
t1++;
}
/**************************************************************************
* interruption for change RB4-RB7
**************************************************************************/
#int_rb
void detect_rb_change(void) {
disable_interrupts(INT_RB);
int current;
static int last=0;
current=PORTB;
if ((!bit_test(current,7))&&(bit_test(last,7))) {
flag=!flag;
if(flag){ //ON
LED_GREEN=1;
state=1;
t3=0;
f_speed();
flag1=1;
} else{ //OFF
LED_GREEN=0;
}
}
last=current;
enable_interrupts(INT_RB);
}
/**************************************************************************
* Main Progran
**************************************************************************/
void main()
{
set_tris_a(0x00);
set_tris_b(0x80);
setup_adc_ports(sAN0);
setup_adc(VSS_VDD | ADC_CLOCK_DIV_8);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_timer_0(T0_INTERNAL|T0_DIV_0);
Clear_LED();
LED_GREEN=0;
SP_OUT=0;
flag=false;
state=1;
f_speed();
t3=0;
t1=0;
set_timer1(53036); //Interrupts 100ms
set_timer0(156); //Interrupts 100us
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_RB);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
if(flag){ //ON
if(t1>10){
t1=0;
f_speed();
}
f_mode_1();
} else{
Clear_LED();
}
}
}
So I'm doing an AT command and the reply is
AT+CGDCONT?
+CGDCONT: 1,"IP","hologram","0.0.0.0",0,0,0,0
+CGDCONT: 13,"IP","hologram","0.0.0.0",0,0,0,0
+CGDCONT: 14,"IP","hologram","0.0.0.0",0,0,0,0
OK
I need to get the numbers out of this that are written before the "IP" (for this example they are 1,13,14). The numbers range from 1-24 as do the number of lines.
I was reading the reply from the command and saving it as a String with
String input;
SerialAT.println("AT+CGDCONT?");
delay(500);
if (SerialAT.available()) {
input = SerialAT.readString();
Serial.println(input);
}
Right now I am reading the stream reply and saving it as a String. The String is then cut at the newline (\n) and stored pieces in an array. After that, I have it read the array and stop once it hits a "," which is right after the number. Then it identifies the section that contains ": " which is right before the number and gets the index position of the ": " and uses that to take a substring of what is left which is just the number.
So for the example that I have, it would put the first row into the array looking like this
+CGDCONT: 1,"IP","hologram","0.0.0.0",0,0,0,0
It would be read one char at a time until the first "," is identified like this
+
+C
+CG
+CGD
+CGDC
+CGDCO
+CGDCON
+CGDCONT
+CGDCONT:
+CGDCONT:
+CGDCONT: 1
then the position of ": " would be identified and for this example, it would be 9. So everything after the 9th position inside of the array would be the output which is 1.
This is working flawlessly and I have even sent in garbled text before the +CGDCONT: because sometimes that's what the modem replies if it didn't have time to fully process the command and it has always fed me the numbers out correctly.
My code for this is
String input;
SerialAT.println("AT+CGDCONT?");
delay(500);
if (SerialAT.available()) {
input = SerialAT.readString();
Serial.println(input);
} else {
Serial.println("Failed to get PDP!");
}
const int numberOfPieces = 10;
String pieces[numberOfPieces];
int counter = 0;
int lastIndex = 0;
for (int i = 0; i < input.length(); i++) {
if (input.substring(i, i + 1) == "\n") {
pieces[counter] = input.substring(lastIndex, i);
lastIndex = i + 1;
counter++;
}
if (i == input.length() - 1) {
pieces[counter] = input.substring(lastIndex, i);
}
}
input = "";
counter = 0;
lastIndex = 0;
String readString, data;
int D;
int PDPcounter = 0;
for ( int i = 0; i < numberOfPieces; i++) {
for ( int x = 0; x < pieces[i].length(); x++) {
char c = pieces[i][x]; //gets one byte from buffer
Serial.println(readString);
if (c == ',') {
if (readString.indexOf(": ") >= 0) {
data = readString.substring((readString.indexOf(": ") + 1));
D = data.toInt();
Serial.println(D);
PDP[PDPcounter] = D;
Serial.print("PDPcounter = "); Serial.println(PDPcounter);
PDPcounter++;
readString = "";
data = "";
break;
}
readString = "";
data = "";
}
else {
readString += c;
}
}
}
At the very end, I try and read the contents of the PDP array with
for ( int i = 0; i < 10; i++) {
Serial.print(i);
Serial.print(" - ");
Serial.println(PDP[i]);
}
and I am getting the following
0 - 1
1 - 13
2 - 14
3 - 0
4 - 0
5 - 0
6 - 0
7 - 0
8 - 0
9 - 0
which is exactly what I need.
I guess the only help that I need now is code cleanup recommendations.
I have a Weather Meter, and I am able to read data from it.
My problem occurs, when I try to use the library UnoWiFiDevEd.h send the data to store the information on the internet.
Arduino tells following:
Global variables use 1648 bytes (80%) of dynamic memory, leaving 400 bytes for local variables.
Maximum is 2048 bytes. Low memory available, stability problems may occur.
I have read, that another means, that the Uno WiFi library itself leads almost 50% Dynamic Memory usage.
Do anyone have an idea, how I can minimize memory usage?
Thank you in advance
#include <UnoWiFiDevEd.h>
//temporary rain
float calcTemp1;
int calcTemp2;
//Wind vane
const float table[16] = {3.84, 1.98, 2.25, 0.41, 0.45, 0.32, 0.90, 0.62, 1.40, 1.19, 3.08, 2.93, 4.62, 4.32, 4.78, 3.43}; //charecter 13 is not correct, but is changed due to failure in windvane
char buffer[20];
//Anometer - windpower
volatile unsigned int windRotation = 0;
//Used for timing
float windTimer = 0;
int angle = 0;
//Rain gauge
float RainMeasurement = 0;
unsigned long LastRainReset = 0;
void setup() {
Serial.begin(9600);
Ciao.begin(); // CIAO INIT
Serial.write(13);
delay(2000);
Serial.println("Initialiserer...");
initWind();
initRain();
Serial.println();
delay(1000);
}
void loop() {
doRequest();
Serial.println();
delay(30000);
}
//Gets data about wind
void getWindData(void)
{
Serial.print("Vindretning: ");
Serial.println(printWindDirection(36));
unsigned long WindReading;
WindReading = Vind_GetHastighed();
sprintf(buffer, "Hastighed: %d m/s ", WindReading);
Serial.println(buffer);
}
//Gets data about rain
void getRainData(void)
{
if (LastRainReset+86400000 < millis()) { // LastRainReset > 24 timer
RainMeasurement = 0;
LastRainReset = millis();
}
calcTemp1 = (float)RainMeasurement;
calcTemp2 = (calcTemp1 - (int)calcTemp1) * 100;
sprintf(buffer, "%0d.%d", (int)calcTemp1, calcTemp2);
Serial.print("Nedb\xF8r: ");
Serial.print(buffer);
Serial.println(" mm");
}
void doRequest(){
String resource = "upload.php?key=secretKey";
resource += "&windDir=";
resource += String(angle);
getWindData();
resource += "&windSpeed=";
resource += String(Vind_GetHastighed());
resource += "&rainAmount=";
getRainData();
resource += String(buffer);
Serial.println(resource);
CiaoData data = Ciao.write("rest", "http://example.com/", resource, "GET");
if (!data.isEmpty()){
Ciao.println( "Link: " + String (resource) );
Ciao.println( "State: " + String (data.get(1)) );
Ciao.println( "Response: " + String (data.get(2)) );
Ciao.println();
}
else{
Ciao.println ("Write Error");
Ciao.println();
}
}
// Initializing processes
void initWind(void)
{
pinMode(3, INPUT);
attachInterrupt(1, windSpeed, RISING);
windTimer=millis();//start timing
Serial.println("* Vindretning");
Serial.println("* Vindhastighed");
}
//initializing rainmeasure
void initRain(void)
{
attachInterrupt(0, Rain_Measure, RISING); //analog port 0
LastRainReset = millis();
Serial.println("* Regn");
}
//Counts amount of rain
void Rain_Measure(void)
{
volatile byte hit = 1;
if (hit == 1) {
hit = 2;
} else if (hit == 2) {
hit = 3;
} else if (hit == 3) {
RainMeasurement = RainMeasurement + 0.2794;
hit = 1;
}
}
//Prints winddirection
String printWindDirection(byte y)
{
// read the analog input into a variable:
String windDir = "unknown";
float voltage = analogRead(0)/204.6;
for (int i = 0; i < 16; i++) {
if (voltage <= table[i]+0.03 && voltage >= table[i]-0.03) {
angle = i;
break;
}
}
//Serial.println(angle); //print the result
switch (angle) {
case 0:
windDir = "N";
break;
case 1:
windDir = "NNE";
break;
case 2:
windDir = "NE";
break;
case 3:
windDir = "E";
break;
case 4:
windDir = "E";
break;
case 5:
windDir = "E";
break;
case 6:
windDir = "SE";
break;
case 7:
windDir = "SSE";
break;
case 8:
windDir = "S";
break;
case 9:
windDir = "SW";
break;
case 10:
windDir = "SW";
break;
case 11:
windDir = "WSW";
break;
case 12:
windDir = "W";
break;
case 13:
windDir = "WNW";
break;
case 14:
windDir = "NW";
break;
case 15:
windDir = "NNW";
break;
default:
break;
}
return windDir;
}
//Prints windspeed
int Vind_GetHastighed()
{
/*
The cup-type anemometer measures wind speed by closing a contact as
a magnet moves past a switch. A wind speed of 1.492 MPH (2.4 km/h)
causes the switch to close once per second.
*/
//Check using Interrupt
float windDtime = millis()-windTimer;
windTimer = millis();
windDtime = windDtime/1000;
float windSpeed = windRotation/windDtime;//rotation per second
windRotation = 0;
windSpeed = windSpeed*2/3;//1 rotation per second equals 2.4 km/h = 2/3 m/s
return int(windSpeed);
}
void windSpeed()
{
windRotation++;
}
Arduino has the F() macro for constant strings to simply indicate that the string should be used from the 'ROM' flash memory of Harvard architecture CPU and not loaded into 'dynamic memory' (RAM). By wrapping constant strings into F macro you reduce the usage of RAM.
The void loop is only running once. Please help. I am inexperienced with Arduino, so any help is much-appreciated. When I open the serial monitor I only see zero once. This code was working earlier today. Sorry if the solution is very simple. Some code has been removed to fit within post restrictions such as ints and ultrasonic declarations and includes.
void setup() {
Serial.begin(9600); //sets up Serial monitor
InfraredSeeker::Initialize();
}
void loop() {
if(u = 1) {
ang = uang;
} else{
ang = irang;
}
Serial.println(uang);
m1 = 200*cos((30-ang)*0.0174533);
m2 = 200*cos((270-ang)*0.0174533);
m3 = 200*cos((150-ang)*0.0174533);
InfraredResult InfraredBall = InfraredSeeker::ReadAC();
switch (InfraredBall.Direction) {
case 1:
irang = 160;
break;
case 2:
irang = 120;
break;
case 3:
irang = 90;
break;
case 4:
irang = 50;
break;
case 5:
irang = 0;
break;
case 6:
irang = 310;
break;
case 7:
irang = 270;
break;
case 8:
irang = 240;
break;
case 9:
irang = 200;
break;
case 0:
irang = 160;
break;
default:
break;
}
lultra = uleft.Ranging(CM);
rultra = urigth.Ranging(CM);
fultra = ufront.Ranging(CM);
if (lultra < 15){
u = 1;
uang = 270;
}
if (rultra < 15) {
u = 1;
uang = 90;
}
if (fultra < 15) {
u = 1;
uang = 180;
}
}