how to generate the getTick() function in keil using stm32cube(HAL library) for stm32l053r8 nucleo board........
void Pedometer::newStep()
{
old_time = new_time; //time in msec of last step
new_time = getTick(); //time in msec of new step
float time = new_time - old_time; //time in msec between
}
Check the HAL_GetTick funtion in CubeL0.
Syntax:
uint32_t HAL_GetTick ( void )
(Refer page no. 56 of the document "Description of STM32L0xx HAL drivers")
Related
I am trying to build communication between a sensor and MSP430F5438a over I2C. Trying to write a code from scratch. Not using any interrupt at this point. Now to read PartID from the sensor I'm following the steps below:
Master issues start condition, sends slave address for write(0b 1010 1110)
Master sends Register address (e.g 0xFF for part id).
Master issues repeated start condition, sends slave address for reading (0b 1010 1111)
Master reads data byte returned from the slave. (Supposed to get back 0x15 which is the PartID).
My issue is I am not getting anything back in my receive buffer. I'm probably doing something wrong in my code. But actually, don't understand where I am doing wrong. Anyone can help in it? My hardware connection is fine I hope (Checked with the sensor provider).
I'm attaching my code below: Wrote it in Code Composer Studio.
#include <msp430.h>
#include <string.h>
#define MAX30101_I2C_ADDRESS 0x57
void Clock_setup(); // default
void I2C_setup();
int readByte(char register_add);
int ID;
void main()
{
WDTCTL = WDTPW + WDTHOLD;
Clock_setup();
I2C_setup();
ID = readByte(0xFF);
}
void Clock_setup(){
P11DIR |= BIT2; // check smclk, 1MHz default
P11SEL |= BIT2; // check smclk, 1MHz default
P11DIR |= BIT0; // check aclk, 32.8KHz default
P11SEL |= BIT0; // check aclk, 32.8KHz default
}
void I2C_setup() {
P3SEL |= BIT7; // 3.7 UCB1_SDA, 5.4 UCB1_SCL
P5SEL |= BIT4;
UCB1CTL1 |= UCSWRST; // reset enable
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // master + I2C mode + Sync
UCB1CTL1 = UCSSEL_2 + UCSWRST; //use SMCLK + still reset
UCB1BR0 = 10; // default SMCLK 1M/10 = 100KHz
UCB1BR1 = 0; //
UCB1I2CSA = MAX30101_I2C_ADDRESS; // MAX30101 7 bit address 0x57
UCB1CTL1 &= ~UCSWRST; // reset clear
}
int readByte(char register_add){
int rx_byte;
UCB1CTL1 |= UCTXSTT+ UCTR; // Generating START + I2C transmit (write)
UCB1I2CSA = 0xAE; // MAX30101 7 bit address 0x57
UCB1TXBUF = register_add; // sending 0xFF to read the PartID
while(!(UCB1IFG & UCTXIFG)); //wait until reg address got sent
while( UCB1CTL1 & UCTXSTT); //wait till START condition is cleared
UCB1CTL1 |= UCTXSTT; //generate RE-START
UCB1I2CSA = 0xAF; // MAX30101 7 bit address 0x57
UCB1CTL1 &=~ UCTR; //receive mode
while( UCB1CTL1 & UCTXSTT); //wait till START condition is cleared
rx_byte = UCB1RXBUF; //read byte
//while(!(UCB1IFG & UCRXIFG)); //wait while the Byte has being read
UCB1CTL1 |= UCTXNACK; //generate a NACK
UCB1CTL1 |= UCTXSTP; //generate stop condition
while(UCB1CTL1 & UCTXSTP); //wait till stop condition got sent
return rx_byte;
}
I²C slave addresses have 7 bits; 0xAF or 0xAE cannot be valid. The comments already say that 0x57 is the correct value.
And you must wait for the received byte to be available (UCRXIFG) before trying to read it.
And this code lacks all error handling; you should at least check for NACK.
I want to understand RTOSs better and therefore started implementing a scheduler. I want to test my code, but unfortunately I have no HW lying around right now. What is an easy way to pretend executing an ISR corresponding to timer in C?
EDIT: Thanks to the answer of Sneftel I was able to simulate a timer interrupt. The code below is inspired by http://www.makelinux.net/alp/069. The only thing I am missing is to do it in a nested way. So if the ISR is running another timer interrupt would cause a new instance of the ISR preempting the first one.
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<signal.h>
#include<sys/time.h>
#include<string.h>
#ifdef X86_TEST_ENVIRONMENT
void simulatedTimer(int signum)
{
static int i=0;
printf("System time is %d.\n", i);
}
#endif
int main(void)
{
#ifdef X86_TEST_ENVIRONMENT
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &simulatedTimer;
sigaction (SIGVTALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = CLOCK_TICK_RATE_MS * 1000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = CLOCK_TICK_RATE_MS * 1000;
/* Start a virtual timer. It counts down whenever this process is executing. */
setitimer (ITIMER_VIRTUAL, &timer, NULL);
#endif
#ifdef X86_TEST_ENVIRONMENT
/* Do busy work. */
while (1);
#endif
return 0;
}
The closest thing in POSIX terms is probably signal handlers; SIGALRM is fired asynchronously within the process in much the same way that an ISR is. There's significant differences in what's safe to do, though, so I wouldn't go too far with the analogy.
I am attempting to send data from device to host using the Gazelle protocol, however, when reading a time varying signal in on MATLAB the values continuously change elements in the array.
Here is the Simblee/Rfduino host code:
#include <SimbleeGZLL.h>
device_t role = HOST;
char array[5];
void setup() {
Serial.begin(9600);
SimbleeGZLL.begin(role);
timer_one(1); // 1 ms timer
}
void loop() {
Serial.flush();
printf(EMG);
}
void SimbleeGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
if (len > 0) {
digitalWrite(2,HIGH);
array[0] = data[0];
array[1] = data[1];
array[2] = data[2];
array[3] = data[3];
array[4] = '\0';
} else SimbleeGZLL.sendToDevice(device, 'A');
}
And the device code:
include
device_t role = DEVICE1;
volatile int state;
char array[4];
void setup() {
SimbleeGZLL.begin(role);
Serial.begin(9600);
timer_one(1);
}
void loop() {
array[0] = analogRead(2);
array[1] = analogRead(3);
array[2] = analogRead(4);
array[3] = analogRead(5);
SimbleeGZLL.sendToHost(EMG,4);
}
Could someone please provide some assistance to identify where the issue may lie?
Thank you!
Matlab is not super reliable with serial communication. I actually had a similar issue with a serial device where the input values would be out of order. Are you signaling when to start and stop printing? What does your matlab code look like?
I would set up a ring buffer on the host and the device to deal with the asycn time issues.
You are going to get timing issues with the current method. What kind of frequency are you going for? The analogRead is super slow, and double multiple in a row seems to make things even slower. Could you try to set up an ADC interrupt?
Where is your timer code?
I have a sketch to take information (Lat, Long) from an EM-406a GPS receiver and write the information to an SD card on an Arduino shield.
The program is as follows:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SD.h>
TinyGPSPlus gps;
SoftwareSerial ss(4, 3); //pins for the GPS
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
void setup()
{
Serial.begin(115200); //for the serial output
ss.begin(4800); //start ss at 4800 baud
Serial.println("gpsLogger by Aaron McRuer");
Serial.println("based on code by Mikal Hart");
Serial.println();
//initialize the SD card
if(!card.init(SPI_FULL_SPEED, 9))
{
Serial.println("card.init failed");
}
//initialize a FAT volume
if(!volume.init(&card)){
Serial.println("volume.init failed");
}
//open the root directory
if(!root.openRoot(&volume)){
Serial.println("openRoot failed");
}
//create new file
char name[] = "WRITE00.TXT";
for (uint8_t i = 0; i < 100; i++){
name[5] = i/10 + '0';
name[6] = i%10 + '0';
if(file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)){
break;
}
}
if(!file.isOpen())
{
Serial.println("file.create");
}
file.print("Ready...\n");
}
void loop()
{
bool newData = false;
//For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
//Serial.write(c); //uncomment this line if you want to see the GPS data flowing
if(gps.encode(c)) //did a new valid sentence come in?
newData = true;
}
}
if(newData)
{
file.write(gps.location.lat());
file.write("\n");
file.write(gps.location.lng());
file.write("\n");
}
file.close();
}
When I open up the file on the SD card when the program is finished executing, I get a message that it has an encoding error.
I'm currently inside (and unable to get a GPS signal, thus the 0), but the encoding problem needs to be tackled, and there should be as many lines as there are seconds that the device has been on. There's only that one. What do I need to do to make things work correctly here?
Closing the file in the loop, and never reopening it, is the reason there's only one set of data in your file.
Are you sure gps.location.lat() and gps.location.lng() return strings, not an integer or float? That would explain the binary data and the "encoding error" you see.
The TypedEvent class has the member variable time. I want to use it to discard too old events. Unfortunately, it is of type int where as System.currentTimeMillis() returns long and both are very different, even when masking them with 0xFFFFFFFFL as the JavaDoc of time is telling me. How should the time be interpreted?
Note: As you haven't mentioned the operating system therefore I am safely assuming it as Windows (because this is what I have got).
Answer
If you closely look at the org.eclipse.swt.widgets.Widget class then you will find that TypedEvent.time is initialized as follows:
event.time = display.getLastEventTime ();
Which in return calls: OS.GetMessageTime ();
Now, SWT directly works with OS widgets therefore on a windows machine the call OS.GetMessageTime (); directly translates to Windows GetMessageTime API.
Check the GetMessageTime on MSDN. As per the page:
Retrieves the message time for the
last message retrieved by the
GetMessage function. The time is a
long integer that specifies the
elapsed time, in milliseconds, from
the time the system was started to the
time the message was created (that is,
placed in the thread's message queue).
Pay special attention to the line from the time the system was started to the time the message was created, which means it is not the standard System.currentTimeMillis() which is the elapsed time, in milliseconds, since 1, Jan 1970.
Also, To calculate time delays between
messages, verify that the time of the
second message is greater than the
time of the first message; then,
subtract the time of the first message
from the time of the second message.
See the below example code, which prints two different messages for time less than 5 seconds and greater than 5 seconds. (Note: It should be noted that the timer starts with the first event. So the calculation is always relative with-respect-to first event). Because of its relative nature the TypedEvent.time might not be suitable for your purpose as the first event may come very late.
>> Code
import java.util.Calendar;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class ControlF
{
static Calendar first = null;
public static void main(String[] args)
{
Display display = new Display ();
final Shell shell = new Shell (display);
shell.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e)
{
long eventTime = (e.time&0xFFFFFFFFL) ;
if(first == null)
{
System.out.println("in");
first = Calendar.getInstance();
first.setTimeInMillis(eventTime);
}
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(eventTime);
long dif = (cal.getTimeInMillis() - first.getTimeInMillis())/1000;
if( dif <= 5)
{
System.out.println("Within 5 secs [" + dif + "]");
}else
System.out.println("Oops!! out of 5 second range !!");
}
});
shell.setSize (200, 200);
shell.open ();
while (!shell.isDisposed()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}