CRGFLG register, last bit not getting set - scale

I'm using a FreeScale 9S12C micro controller and am coding in Code Warrior. I'm trying to create a SEQ detector for Sequence 10011. When I do a simulation the program gets stuck in the function DelayGate, everything else appears ok. It seems that the last bit in the CRGFLG register is never getting set like it's supposed to. I believe it's supposed to get set at the end of every real time clock cycle. I set RTICTL = 0b01000000, so the real time clock should have a period of 1.024 ms. So my expected behavior is that the program should stay in the DelayGate for approximately 1.024 ms and than exit, but the program stays in delay gate for ever and never exits. It appears that the last bit in CRGFLG never gets set for some reason, and I'm not sure why. Thanks for any help anyone can provide me! Here's my code. I'm using a 8 MHz crystal.
// Constants
#define CRYSTAL_CLOCK_FREQ 8000000L //set the clock to 8 MHz?
#define LED_COUNT_MAX 488 //(500 ms)/(1.024 ms) about 488
// Includes
#include <hidef.h> /* common defines & macros */
#include "derivative.h" /* derivative-specific */
// Prototypes
void SysInit(void);
void UpdateLED(void);
int input;
int state;
int nn = 5;
int value;
void Delay(int nn);
int UpdateStatetask(int input, int state);
void DelayGate(void);
int BeepFlag = 0;
int done = 0;
#endif
/*****************************************************
* main - Program main
****************************************************/
void main(void){
COPCTL = 0x00; // Disable the COP timer
RTICTL = 0b01000000; //8 MHz crystal, period of real time clock is 1.024 ms
PTT = 0x00; // initally all logical zero
DDRT = 0b11111100; // PT0 "0" input
//PT1 "1" input
//PT2 SEQ state 1 indication
// PT3 SEQ state 2 indication
// PT4 SEQ state 3 indicaiton
// PT5 SEQ state 4 indication
// PT6 SEQ detection
// PT7 LED Clock
PERT = 0b11111111; // enable pulling on all port T
PPST = 0b11111111; // pull-down to ground all port T
CLKSEL = 0x00;
PLLCTL = 0x00;
CRGINT = 0b10000000;
while (1){
UpdateLED();
DelayGate();
}
}
/**************************************************
* UpdateLED()
* When the LED count runs out, toggle and beep
*************************************************/
void UpdateLED(void){
static int state = 0;
int input;
int LedCount = LED_COUNT_MAX; //488*1.024 ms = 0.4997 s
if (--LedCount == 0){ //decrement LED count
LedCount = LED_COUNT_MAX;
PTT = 0b10000000; //turn on LED clock
}
if (PTT & 0x01 == 1){ //bitwise and, checking for clock LED
if(PTT & 0b00000001){ //"0" input
input = 0;
}
if(PTT & 0b00000010){ //"1" input
input = 1;
}
}
UpdateStatetask(input,state);
}
/**************************************************
* UpdateStatetask()
*************************************************/
int UpdateStatetask(input, state){
switch(state){
case 0:
PTT = 0b00000000; //state 0 no LEDs should light up
if (input == 0){ //SEQ = 10011
state = 0; //if "0" is entered at state zero stay at state zero
}
else if(input == 1){
state = 1; //if "1" is entered at state zero go to state 1
}
break;
case 1:
PTT = 0b00000100; //turn on LED indicating state 1
if (input == 0){ //if "0" is entered at state one go to state two
state = 2;
}
else if(input == 1){ //if "1" is entered at state one stay at state one
state = 1;
}
break;
case 2:
PTT ^= 0b00001100; //state 2 indication turn on 2 LED
if (input == 0){ //if "0" is entered at state two go to state three
state = 3;
}
else if(input == 1){ //if "1" is entered at state two go to state one
state = 1;
}
break;
case 3:
PTT = 0b00011100; //state 3 indication turn on 3 LED
if (input == 0){ //if "0" is entered at state three go to state zero
state = 0;
}
else if(input == 1){ //if "1" is entered at state three go to state four
state = 4;
}
break;
case 4:
PTT = 0b00111100; //state 4 indication turn on 4 LED
if (input == 0){ //if "0" is entered at state four go to state 2
state = 2;
}
else if(input == 1){//if "1" is entered at state four go to state 1
PTT = 0b01111100; //SEQ detection turn on 5 LED
state = 1;
}
break;
default:
state = 0;
break;
}
return state;
}
/**************************************************
* DelayGate
* Wait for timeout, then restart the RTI clock
*************************************************/
void DelayGate(void){
while ( (CRGFLG & 0x80) == 0){
;
}
CRGFLG = 0x80;
}
When I compile the only warnings I get is that
result of function call is ignored on this line: UpdateStatetask(input,state)
This is the old style of function call here on this line: int UpdateStatetask(input, state){
These warnings shouldn't cause the problem I'm having. Thanks for any help!

Related

Can I use float to store millis function return value as done in the code?

Can I use float data type to store the return value of millis function as shown on the code here? I saw unsigned int type to do it. But look I'm converting that millis to hour. That's why I'm trying to store in float.
#include<Servo.h>
#include<math.h>
Servo mark1;
float dur = 2.30, del_dur = 0 ;
float sys_strt = (millis()/3600000), curr_tim = (millis()/3600000), del_strt = 0;
float inc_val;
const int relay_on = 8;
//2, output = 9;
void setup()
{
digitalWrite(8, HIGH);
mark1.attach(9);
mark1.write(110);//servo on
Serial.begin(9600);
// pinMode(switch_on, INPUT);
// pinMode(output, OUTPUT);
}
void loop()
{
if(Serial.available() > 0)
{
inc_val = Serial.read();
Serial.print("\n");
if(inc_val == 'D') // D = DURATION
{
delay(2000);
dur = Serial.read();
sys_strt = (millis()/3600000);
//mark1.write(on);
}
else if(inc_val == 'd') // d = delay_duration_for_future_turn_on
{
mark1.write(158);// servo off
delay(2000);
del_dur = Serial.read();
Serial.print("\n");
delay (5000);
dur = (Serial.read() + del_dur);
del_strt = (curr_tim + del_dur);
sys_strt = del_strt;
//curr_tim = (millis()/1000);
}
}
if((millis()/3600000) >= 5)
{digitalWrite( 8, LOW);}
if(((millis()/3600000) - del_strt) >= 0 && ((millis()/3600000) - del_strt) <=10 ) // statement for delay duration process
{
mark1.write(110);// servo on
}
if(((millis()/3600000)-sys_strt) >= dur)
{
mark1.write(158);//servo off
}
}
//int x = ((millis() / 1000) - off_timer_start) / 60;
// if (digitalRead(switch_on) == HIGH)
//{
// off_timer_start = (millis() / 1000);
//digitalWrite(output, HIGH);
//}
//else if (x >= offtime && digitalRead(output == HIGH)) {
//digitalWrite(output, LOW);
//}
//delay(1000);
I was trying to store millis return value in float variable. But not sure whether it'll work or not.
There is no need to use float, millis() return an unsigned long which is a 32-bit integer (i.e. equivalent to uint32_t).
Instead of doing division, which is more computationally intensive and has to be done in the runtime for thing like millis()/3600000, you could use 5*3600000 (which is a constant, and the compiler will optimize it to a constant of 18000000 during the compilation) for representing 5 hours. So instead of doing
if((millis()/3600000) >= 5) // do something
it can be done as:
if((millis() >= 5*3600000) // do something
or even better you could define the constant to make your code more readable as:
unsigned long fiveHour = 5*3600000;
if ((millis() >= fiveHour) // do something
It appears that the Arduino related millis() function returns unsigned long, so you cannot store it with full precision in a float.

Want the numbers in between two limits with equal time interval

I try to get values in between 10 and 100 so I arrange
int pos;
long previousTime =0;
int increment = 1;
int interval = 10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
long currentTime = millis();
if(currentTime - previousTime > interval){
previousTime = currentTime;
pos +=increment;
if(pos<= 10 || pos > 100){
increment = -increment;
}
Serial.println(pos);
}
}
But my output showing only 1 and 0.If I reduce lower limit into 0 or 1 then I got values in between those limit values given inside the if statement but not getting proper result when I increase the lower limit.Why?
Ok your problem is simple now that we can see the whole code. Look at position, it starts out at 0. On the first pass through loop it gets increments to 1. Then that if statement checks and 1 is indeed less than 10 so it makes increment -1. Then on the next pass through loop that gets added making pos 0 again and since 0 is less than 10 it reverses increment again. It’s doing exactly what you told it.
Try starting pos out at the 10 and see what happens.
If it's not trivial to you, here a suggestion
int pos=0;
unsigned long previousTime =0;
int increment = 1;
int interval = 10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
unsigned long currentTime = millis();
if(currentTime - previousTime >= interval){
previousTime = currentTime;
pos += increment;
if(pos <= 10) increment = 1;
if(pos >= 100) increment = -1;
// else leave increment as is ...
Serial.println(pos);
}
}

Get 3 Values from processing to Arduino

I have a color tracking program in Processing, which works with a Kinect. When I click somewhere in the picture it saves this color and draws an ellipse around it. I just want to send 3 int values (one for red, green and blue) over myPort.write() to Arduino and save these 3 values in Arduino in 2 variables. My goal is to light a red LED if the red variable is the highest, and the green LED if green is the highest and so on.
I've tried several examples I found whiel googling, but nothing works. I don't know how Arduino should get the correct values in the variables!
EDIT: Here you have my Processing code. I glued it together from several other tutorials until I nearly cried..
import processing.serial.*;
Serial myPort;
import SimpleOpenNI.*;
SimpleOpenNI kinect;
// Frame
PImage currentFrame;
color trackColor;
int r1, g1, b1, r2, g2, b2;
void setup()
{
size(640, 480);
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600);
kinect = new SimpleOpenNI(this);
kinect.enableRGB();
trackColor = color (255, 0, 0);
smooth ();
currentFrame = createImage (640, 480, RGB);
}
void draw()
{
kinect.update();
currentFrame = kinect.rgbImage ();
image(currentFrame, 0, 0);
currentFrame.loadPixels();
// Before we begin searching, the "world record" for closest color is set to a high number that is easy for the first pixel to beat.
float worldRecord = 500;
// XY coordinate of closest color
int closestX = 0;
int closestY = 0;
// Begin loop to walk through every pixel
for (int x = 0; x < currentFrame.width; x ++ ) {
for (int y = 0; y < currentFrame.height; y ++ ) {
int loc = x + y*currentFrame.width;
// What is current color
color currentColor = currentFrame.pixels[loc];
r1 = (int)red(currentColor);
g1 = (int)green(currentColor);
b1 = (int)blue(currentColor);
r2 = (int)red(trackColor);
g2 = (int)green(trackColor);
b2 = (int)blue(trackColor);
// Using euclidean distance to compare colors
float d = dist(r1, g1, b1, r2, g2, b2); // We are using the dist( ) function to compare the current color with the color we are tracking.
// If current color is more similar to tracked color than
// closest color, save current location and current difference
if (d < worldRecord) {
worldRecord = d;
closestX = x;
closestY = y;
}
}
}
// We only consider the color found if its color distance is less than 10.
// This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.
if (worldRecord < 10) {
// Draw a circle at the tracked pixel
fill(trackColor);
strokeWeight(4.0);
stroke(0);
ellipse(closestX, closestY, 30, 30);
}
if (mousePressed == true) {
color c = get(mouseX, mouseY);
//println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));
// Save color where the mouse is clicked in trackColor variable
int loc = mouseX + mouseY*(currentFrame.width);
trackColor = currentFrame.pixels[loc];
println("red " + r2);
println("green " + g2);
println("blue " + b2);
int colors[] = {r2, g2, b2};
for(int i=0; i < 3; i++) {
myPort.write(colors[i]);
}
}
println("ClosestX " + closestX);
myPort.write(closestX);
}
And my Arduino Code, where I don't know how to get several values.
int val;
int ledPin = 13;
int freq;
int piezoPin = 9;
int redLED = 3;
int greenLED = 5;
int blueLED = 7;
int red, green, blue;
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
digitalWrite(ledPin, LOW);
}
void loop() {
if (Serial.available() > 0)
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if(red > green && red > blue) {
digitalWrite(redLED, HIGH); //light Red LED
}
if(green > red && green > blue) {
digitalWrite(greenLED, HIGH); //light Red LED
}
if(blue > red && blue > green) {
digitalWrite(blueLED, HIGH); //light Red LED
}
//Piezo buzzing higher when X-Position of tracked color is higher.
if (val < 100) {
freq = 50;
}
else if (val < 200) {
freq = 200;
}
else if (val < 300) {
freq = 400;
}
else if (val < 400) {
freq = 600;
}
else if (val < 500) {
freq = 800;
}
else (freq = 1000);
tone(piezoPin, freq);
}
EDIT2: Yes, additionally to lighing the LEDs I also want to have a sound from a piezo buzzer, but that works pretty well, so no questions on that... yet.
Help, please!!
Serial communication to your arduino works with a single byte at a time.
As luck would have it, the three components of a Processing Color are also three bytes.
One for red(0-255)
One for green(0-255)
One for blue(0-255)
Now all we need is a little more info so we can keep them separate.
Because a byte's minimum and maximum values are 0-255, there's no safe character we can use to keep track of the three different bytes, so we need a way to figure out where the info we send begins and ends.
An easy way to do this, is to set up a header and a footer for your messages ; something like :
<color>[byte (red)][byte (green)][byte (blue)]</color>
If we are going to read and decipher messages formatted like this, we are going to need a little buffer that will store the values we receive from Processing, so we can read them back and see if we can match the message format.
So, on the Arduino side, we need this :
String buffer = "";
String messageBegin = "<color>";
String messageEnd = "</color>";
//we read our serial data in the SerialEvent() function
//this is called *after* a loop(), and only if there is serial data in the buffer.
void serialEvent()
{
while(Serial.available())
{
buffer += (char)Serial.read();
}
}
void loop()
{
//now, inside loop, we no longer need to worry about gathering data from serial.
//we do still need to figure out if our message is complete, and then parse it.
//if our buffer contains both the beginning and the end of a message
//in the right order.
int beginIndex = buffer.lastIndexOf(messageBegin);
int endIndex = buffer.lastIndexOf(messageEnd);
if(beginIndex != -1 && endIndex != -1 && beginIndex < endIndex)
{
//we have a complete message!
//our red color starts 7 characters after where the message begins,
//because our "messageBegin" is 7 characters long
string lastMessage = buffer.substring(beginIndex+7);
//this is arguably not the prettiest way to get our byte values back.
//see if you can do better for bonus points!
byte messageAsBytes[80];
lastMessage.getBytes(messageAsBytes, messageAsBytes.length());
//we can now finally reconstruct the value we had from processing!
byte r = (byte)messageAsBytes[0];
byte g = (byte)messageAsBytes[1];
byte b = (byte)messageAsBytes[2];
//if we get a complete message, we can clear our buffer. (don't forget to do this!)
buffer = "";
}
}
On the processing side, all we need to do is make sure our messagebegin and messageend are sent along for the ride :
myPort.write("<color">);
for(int i=0; i < 3; i++) {
myPort.write(colors[i]);
}
myPort.write("</color">);

Arduino sensor data

Hi I am using an Arduino Flex sensor to control a video game character.
The sensor data is being averaged and remapped to a value of between 0-6.
When the player flexes their bicep it reads the max value (this is perfect) however if the player flexes their arm hard and the sensor reads a max value of 6 for some reason as the player relaxes their arm the declining flex values are being passed into the game engine (instead of going from 6 to zero it drops from 6 to 5 to 4 to 3 to 2 to 1 before reaching zero). Can someone please advise how I should alter my code to make the sensor reading return to 0 instead of declining gradually?
#define NUM_LED 6 //sets the maximum numbers of LEDs
#define MAX_Low 75 //for people with low EMG activity
#define MAX_High 150//for people with high EMG activity
#define Threshold 3 // this sets the light to activate TENS
int reading[10];
int finalReading;
int MAX = 0;
int TENS =3;
int ledState = LOW;
byte litLeds = 0;
byte multiplier = 1;
byte leds[] = {8, 9, 10, 11, 12, 13};
char ch;
char contact;
void setup(){
Serial.begin(9600); //begin serial communications
digitalWrite(TENS, LOW);
for(int i = 0; i < NUM_LED; i++){ //initialize LEDs as outputs
pinMode(leds[i], OUTPUT);
pinMode(TENS, OUTPUT); // Set TENS output to StimPin
}
MAX = MAX_High; //This sets the default to people with high EMG activity.
}
void loop(){
for(int i = 0; i < 10; i++){ //take ten readings in ~0.02 seconds
reading[i] = analogRead(A0) * multiplier;
delay(2);
}
for(int i = 0; i < 10; i++){ //average the ten readings
finalReading += reading[i];
}
finalReading /= 10;
for(int j = 0; j < NUM_LED; j++)
{
digitalWrite(leds[j], LOW);//write all LEDs low and stim pin low
}
finalReading = constrain(finalReading, 0, MAX);
litLeds = map(finalReading, 0, MAX, 0, NUM_LED);
Serial.println(litLeds);
for(int k = 0; k < litLeds; k++){
digitalWrite(leds[k], HIGH); // This turns on the LEDS
}
{
// send data only when you receive data:
if (Serial.available() > 0)
{
ch = Serial.read();
contact=digitalRead(TENS);
if (ch == 'A' && contact==LOW)
{
digitalWrite(TENS, HIGH);
}
else if (ch == 'B' && contact==HIGH)
{
digitalWrite(TENS, LOW);
}
}
}
delay(80);
}
Your sensor doesn't read 6 and immediately 0, you are reading it so fast that you can read the intermediate values. For example: if player opens the arm very fast (250-300 ms, it is fast), you can take up to 3 readings then you can read 3 intermediate values.
You can add more time to the last delay() or use only a value that is the same that the 3 last readings to ensure that there isn't a fast change.

1820 Dallas Temperture sensor, incorrect value returned

When I run a piece of code that only gathers values from the temp sensor it returns the correct values.
when I integrate this functionality into a larger piece of code it constantly returns -127 degrees.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPP.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature TempSensor(&oneWire);
USB Usb; // create usb
BTD Btd(&Usb); // create bluetooth dongle instance
SPP SerialBT(&Btd, "Arduino", "0000"); // set device name and pin
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // create lcd instance using declared pins
int LightPin = A0; // pin connected to light sensor
int LcdType = 0; // variable for lcd display
int state; // variable for storing incoming data
int LDRvalue = 0; // value from light sensor
int totalLdr = 0;
int totalLdrNums = 0;
String output = ""; // output string for light sensor
String output2 = ""; // output string for temp sensor
int tempvalue = 0; // value from temp sensor
int totalTemp = 0;
int totalTempNums = 0;
float celsius = 0; // temp in celsius
void setup() {
Serial.begin(9600); // Begin serial comms at speed 9600
if (Usb.Init() == -1) { // if usb hasn't been initilsed
while(1); //wait
}
lcd.begin(16, 2); // set up lcd with 16 coloums and 2 rows
pinMode(LightPin, INPUT); // declare light pin as input
printStart(); // run printStart method
LcdType = 1; // set lcd display type to 1
TempSensor.begin();
}
void loop() {
Usb.Task(); // polls connected devices for status
if(SerialBT.connected) { // if BT connected
if(SerialBT.available() > 0){ // and BT is available
state = SerialBT.read() - '0'; // read incoming value and turn into regular int (0 - 9 in ascii is 48 - 57)
if(state == 0){ // if value read is zero
checkLightValue(); // run checkLightValue method
SerialBT.write(output[0]); // send first value in string
delay(50); // delay before sending next value
SerialBT.write(output[1]); // send second value
delay(50); // delay before sending next value
SerialBT.write(output[2]); // send third value
}
if(state == 1){ // if value read is 1
checkTempValue();
SerialBT.write(output2[0]); // send first value
delay(50); // delay before sending next value
SerialBT.write(output2[1]); // send second value
delay(50); // delay before sending next value
SerialBT.write(output2[3]); // send third value
delay(50); // delay before sending next value
SerialBT.write(output2[5]); // send fourth value
delay(50); // delay before sending next value
}
if(state == 2){
//Restart();
SerialBT.disconnect();
}
if(state == 3){
LcdType = 1;
}
if(state == 4){
LcdType = 2;
}
if(state == 5){
LcdType = 3;
}
if(LcdType == 1){ // if lcd type variable = 1
printLcd();} // run printLcd method
if (LcdType == 2){
printLcd2();
}
if(LcdType == 3){
printLcd3();
}
}
}
}
//void (*resetFunc)(void) = 0;
void checkLightValue(){
output = ""; // reset output string to nothing
LDRvalue = analogRead(LightPin); // read in light value
totalLdr = totalLdr + LDRvalue;
totalLdrNums = totalLdrNums + 1;
int LDR1 = LDRvalue / 100; // get int 1 from value
int twod = LDRvalue - (LDR1 * 100); // get int 2 and 3 from value
int LDR2 = twod / 10; // get int 2 from value
int LDR3 = twod - (LDR2 * 10); // get int 3 from value
output += LDR1; //
output += LDR2; //
output += LDR3; // appends values to string
}
void checkTempValue(){
output2 = ""; // reset output string to nothing
TempSensor.requestTemperatures();
Serial.println(TempSensor.getTempCByIndex(0));
celsius = TempSensor.getTempCByIndex(0);
totalTemp = totalTemp + celsius;
totalTempNums = totalTempNums + 1;
int c1 = celsius / 100; // get first int from value
int twod = celsius - (c1 * 100); //
int c2 = twod / 10;
int c3 = twod - (c2 *10);
output2 += c1; //
output2 += c2; //
output2 += c3; // add values to string to send
}
void printLcd(){
lcd.clear(); // clear lcd
lcd.print("LDR : "); lcd.print(LDRvalue); // display current ldr value
lcd.setCursor(0,1); // set cursor to second row
lcd.print("Temp : "); lcd.print(celsius); // display current temp value on row 2
}
void printLcd2(){
int Averagevalue = totalLdr / totalLdrNums;
lcd.clear();
lcd.print("Average light :");
lcd.setCursor(0,1);
lcd.print(Averagevalue);
}
void printLcd3(){
int Averagevalue = totalTemp / totalTempNums;
lcd.clear();
lcd.print("Average temp :");
lcd.setCursor(0,1);
lcd.print(Averagevalue);
}
void printStart(){
lcd.clear(); // clear lcd
lcd.setCursor(1,1); // set cursor on second row
lcd.print("Waiting for a Connection ?"); // print message
for(int x=1; x<16; x++) { // do following 15 times
lcd.setCursor(x,0); // set cursor to first row
lcd.print("Arduino Started"); // print message // doing this as lcd scrolls means the top line (message) appears static while the bottom line (message) scrolls
lcd.scrollDisplayLeft(); // scroll display left
delay(250); // delay before moving again
}
}

Resources