How to use TSL2301 and make clock delay in usart - sensors

I am working on a line scan ccd sensor named TSL2301 .I want to read pixels by USART of stm32f103 but always i just could receive 0xFF , did anybody work with this sensor to help me?
I used Usart synchronous mode of STM32f10x , I sent some order to sensor by Usart and want to make 8 clock delay after each order . how can i do it?
int count=0;
int i=0;
uint8_t data[102]={0};
USART_ClockInitStructure.USART_Clock = USART_Clock_Enable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Enable;
USART_ClockInit(USARTy, &USART_ClockInitStructure);
USART_InitStructure.USART_BaudRate = 2200000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTy, &USART_InitStructure);
/* Configure the USARTy */
USART_Init(USARTy, &USART_InitStructure);
/* Enable the USARTy */
USART_Cmd(USARTy, ENABLE);
while(1)
{
while(count < 3)
{
USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;
}
count=0;
USART_SendData(USARTy,0x1b); //RESET command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
USART_SendData(USARTy,0x1b);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
USART_SendData(USARTy,0x1b);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
USART_SendData(USARTy,0x08); //StartInt Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
while(count < 20 )//DelayIntegrationTime() ;
{
USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;
}
count = 0;
USART_SendData(USARTy,0x10); //SampleInt Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
USART_SendData(USARTy,0x02); //ReadPixel Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
while(count < 2)
{
USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;
}
count = 0;
USART_Cmd(USARTy, DISABLE);
USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge;
USART_ClockInit(USARTy, &USART_ClockInitStructure);
USART_Init(USARTy, &USART_InitStructure);
USART_Cmd(USARTy, ENABLE);
/*read pixels*/
for (i = 0; i < 102; i++)
{
while(USART_GetFlagStatus(USARTy, USART_FLAG_RXNE) == RESET);
data[i] = USART_ReceiveData(USARTy);
while(count < 1)
{
USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;
}
count = 0;
}
USART_Cmd(USARTy, DISABLE);
USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInit(USARTy, &USART_ClockInitStructure);
USART_Init(USARTy, &USART_InitStructure);
USART_Cmd(USARTy, ENABLE);
}

There is different USART timing diagrams in STM32F103 reference manual and TAOS datasheet.
I think they will not work together in USART mode.
As an Idea, you can try to use UART instead of USART. And clock the device using MCO or other clock source. I think it should work.
It this case all delays you can do with timer.
PS: But there is one more problem you should solve, is to synchronize output of UART with clock source. I need to read stm32 manual more carefuly to tell you how to do it. I'll do it later

Related

MSP432 GPIO Output Voltage Too Low

I'm an undergraduate student. We have an assignment to use Energia and the MSP432-P401R microcontroller to create an OR gate and AND gate IC tester.
You place the IC in the tester circuit and the tester will first determine if the IC is an AND or OR IC. Then, it will indicate which gates on the chip are functioning properly.
My issue is regrading the logical HIGH output voltage of the MSP432. My input signals, a and b, are passed to the IC gates. When my "a" signal is logical HIGH, its voltage is 2.8V. When my "b" signal is logical HIGH, its voltage is 0.7V. This 0.7V is too low for my ICs to register as a HIGH input. I am reading the voltage directly from the MSP432 pin.
I have tried using different GPIO pins and resetting the board. However, the "b" signal is still 0.7V.
My code for setting up "a" and "b" are similar, so I'm not sure why they are outputting different voltages.
My code:
//IC TEST
//Gate inputs pin assignment
int APin=11;
int BPin=8; //other pins tried: 12, 18, 5
//Gate output read pins
int output1Pin=38;
int output2Pin=37;
int output3Pin=36;
int output4Pin=35;
//LED pins
int gate1LEDPin=31;
int gate2LEDPin=32;
int gate3LEDPin=33;
int gate4LEDPin=34; //Gate functioning indicators
int orLEDPin = 40;
int andLEDPin= 39; //Logic of IC indicators
//Truth Table Arrays with inputs a and b
int aValue[]={0, 0, 1, 1};
int bValue[]={0, 1, 0, 1};
int orTrue[]={0, 1, 1, 1};
int andTrue[]={0, 0, 0, 1};
//Function Declaration
int workTest(int,int); //checks if gate is working
//by comparing gate output to
//expected truth result
int logicTest(); //Returns 0 for OR IC, 1 for AND IC
//Progrram variables
int i; //for loop counter
int gate1Result;
int gate2Result;
int gate3Result;
int gate4Result; //Stores number of times gate outputs
//correct value for each ab input
int logicRead; //0 is OR gate. 1 is AND gate
//--------------SETUP-----------------
void setup()
{
Serial.begin(9600);
pinMode(APin, OUTPUT);
pinMode(BPin, OUTPUT);
pinMode(output1Pin, INPUT);
pinMode(output2Pin, INPUT);
pinMode(output3Pin, INPUT);
pinMode(output4Pin, INPUT); //gate output reads
pinMode(orLEDPin, OUTPUT);
pinMode(andLEDPin, OUTPUT);
pinMode(gate1LEDPin, OUTPUT);
pinMode(gate2LEDPin, OUTPUT);
pinMode(gate3LEDPin, OUTPUT);
pinMode(gate4LEDPin, OUTPUT);
}
//END SETUP
//-----------------LOOP---------------------
void loop()
{
gate1Result = 0;
gate2Result = 0;
gate3Result = 0;
gate4Result = 0;
//test IC for its logic function
logicRead = logicTest(); //logicTest returns 0 for OR, 1 for AND
if(logicRead == 9) //logic of IC cannot be determined
{
Serial.println("Try again");
}
if(logicRead != 9)
{
for(i=0; i<4; i++)
{
digitalWrite(APin, aValue[i]); //Load ith value of aValue array
digitalWrite(BPin, bValue[i]); //Load ith value of bValue array
Serial.print("AB = ");
Serial.print(aValue[i]);
Serial.println(bValue[i]);
delay(4000); //Stabilize input signals
if(logicRead == 0) //OR Testing
{
Serial.print("OR Output should be ");
Serial.println(orTrue[i]);
Serial.print("Gate 1: ");
gate1Result = gate1Result + workTest(orTrue[i], output1Pin);
Serial.print("Gate 2: ");
gate2Result = gate2Result + workTest(orTrue[i], output2Pin);
Serial.print("Gate 3: ");
gate3Result = gate3Result + workTest(orTrue[i], output3Pin);
Serial.print("Gate 4: ");
gate4Result = gate4Result + workTest(orTrue[i], output4Pin);
}
if(logicRead == 1) //AND Testing
{
Serial.print("AND Output should be ");
Serial.println(andTrue[i]);
Serial.print("Gate 1: ");
gate1Result = gate1Result + workTest(andTrue[i], output1Pin);
Serial.print("Gate 2: ");
gate2Result = gate2Result + workTest(andTrue[i], output2Pin);
Serial.print("Gate 3: ");
gate3Result = gate3Result + workTest(andTrue[i], output3Pin);
Serial.print("Gate 4: ");
gate4Result = gate4Result + workTest(andTrue[i], output4Pin);
}
}
//Write gate 1 LED
if(gate1Result == 4)
{
digitalWrite(gate1LEDPin, HIGH);
Serial.println("Gate 1 works");
}
else
{
digitalWrite(gate1LEDPin, LOW);
Serial.println("Gate 1 FAIL");
}
//Write gate 2 LED
if(gate2Result == 4)
{
digitalWrite(gate2LEDPin, HIGH);
Serial.println("Gate 2 works");
}
else
{
digitalWrite(gate2LEDPin, LOW);
Serial.println("Gate 2 FAIL");
}
//Write gate 3 LED
if(gate3Result == 4)
{
digitalWrite(gate3LEDPin, HIGH);
Serial.println("Gate 3 works");
}
else
{
digitalWrite(gate3LEDPin, LOW);
Serial.println("Gate 3 FAIL");
}
//Write gate 4 LED
if(gate4Result == 4)
{
digitalWrite(gate4LEDPin, HIGH);
Serial.println("Gate 4 works");
}
else
{
digitalWrite(gate4LEDPin, LOW);
Serial.println("Gate 4 FAIL");
}
}
Serial.println();
Serial.println();
delay(10000); //Wait 10 sec before running code again
}//End void loop
//-----------Function Definitions-----------------------
//This function tests if all gates of the IC are working
//Returns 1 if gate is functioning
//Returns 0 if gate is not functioning
int workTest(int truth, int gateNum)
{
int gateRead = 0; //Updates for each gate output
int result = 0; //TotResult is 1 for all gates pass, 0 for any gate fail
gateRead= digitalRead(gateNum);
if(gateRead == truth)
{
result = 1;
}
else
{
result = 0;
}
Serial.println(gateRead);
return result; //1 for pass, 0 for gate fails
}
//This function tests the logic of the IC
//Returns 1 if IC is an AND gate
//Returns 0 if IC is an OR gate
//Allows for 1 broken gate
//If more than 1 gate broken, logic cannot
//be determined
int logicTest()
{
int aVal[]={0, 1};
int bVal[]={1, 0};
int outputCount = 0;
int logicGate = 0;
int c;
int gate1;
int gate2;
int gate3;
int gate4;
for(c=0; c<2; c++) //only testing ab = 01 and ab = 10
{
digitalWrite(APin, aVal[c]);
digitalWrite(BPin, bVal[c]);
delay(1000); //Stabilize input delay
gate1=digitalRead(output1Pin);
gate2=digitalRead(output2Pin);
gate3=digitalRead(output3Pin);
gate4=digitalRead(output4Pin);
outputCount = outputCount + gate1 + gate2 + gate3 + gate4;
}
if(outputCount < 3) //IC is likely AND gate w/ 1 broken gate
{
logicGate = 1;
Serial.println("IC is an AND gate");
digitalWrite(andLEDPin, HIGH);
digitalWrite(orLEDPin, LOW);
}
else if(outputCount > 5 && outputCount < 9) //IC is likely OR gate w/ 1 broken gate
{
logicGate = 0;
Serial.println("IC is an OR gate");
digitalWrite(andLEDPin, LOW);
digitalWrite(orLEDPin, HIGH);
}
else
{
logicGate = 9;
digitalWrite(andLEDPin, LOW);
digitalWrite(orLEDPin, LOW);
Serial.println("Logic of IC could not be determined");
Serial.println("IC could be broken. Make sure IC is connected properly.");
Serial.println();
}
return logicGate;
}
Here is the circuit setup:

Select in loop - work all the time - linux

I got next question about select:
How to make select in loop ?
I try to do like that:
struct timeval timeout;
int sel;
size_t rozmiar = sizeof(pid_t);
char buf[rozmiar];
int i;
FD_ZERO(&set);
for(i = 0; i< val; i++)
{ FD_SET(fd[i][0], &set); // val -> N pipe2
}
timeout.tv_sec = 2;
timeout.tv_usec = 0;
while(1)
{
sel = select(val+1,&set,NULL,NULL,&timeout);
if(sel < 0)
perror("select");
else if(sel == 0)
printf("No communicate \n");
else{
for(i = 0; i < val; i++)
{
if(FD_ISSET(fd[i][0],&set))
{
while(read(fd[i][0],&buf,rozmiar) > 0)
write(1,&buf,rozmiar);
} // check if exist and write to stdout
}
} // end SELECT
timeout.tv_sec = 2;
timeout.tv_usec = 0;
}
But there all the time show: ,, no communicate". Is it the correct way to create select which work all the time? I am not sure so I prefer to ask. I try to find information in books but with no lucky.
The set is changed by select, you need to refill it each time

Sound sensor's embedded green light blinking with noise but external LED not

I bought a sound sensor ( 3 pins VCC GND OUT).
I connected all the pins correctly (I think)
VCC to 5V
GND to GND
OUT to A0
But when I upload the code into the arduino uno then the internal green light of sound sensor is blinking with the sound like music. But any LED at breadboard doesn't.
the value of the function sensorValue = analogRead(A0); return almost same value while making noise. After calibrating the sensor the value is also almost same.
Here my Code
#define out A0
int th = 320;
int sensorValue = 0;
int pins[3] = {10,11,12};
void setup(){
int i;
for( i = 0; i<3; i++ ){
pinMode(pins[i], OUTPUT);
}
//pinMode(out,INPUT);
Serial.begin(9600);
}
void loop(){
// sensorValue = analogRead(OUT);
sensorValue = analogRead(out);
int chk = digitalRead(out);
Serial.print("sensorValue: ");
Serial.println(sensorValue);
Serial.print("digitalRead: ");
Serial.println(chk);
int i=0;
if( sensorValue > th){
for( i = 0; i<3; i++){
digitalWrite(pins[i],HIGH);
}
}else{
for( i = 0; i<3; i++){
digitalWrite(pins[i],LOW);
}
}
}
What's wrong with it?

2 PIR motion sensors +Arduino

My project is to allow automatic lightening by detecting motion using PIR Sensors.
THis is what I want to do :
when the first motion sensor "inputpin" is HIGH which means a motion1 is detected , ledPin1 is set to HIGH.... then I check the signal from the other PIR sensor "inputpin2" if it is HIGH ledPin3 should be HIGH , If it is LOW ledpin2 should be HIGH.
I wrote this code , but what it actually do is after a motion is detected from the first sensor"inputPin" , ledPin3 is set to high as if the second sensor is always HIGH !
Can any one help me with this problem.
Thanks
` ``
int ledPin1 = 13; // choose the pin for the LED
int ledPin2 = 12;
int ledPin3 = 11;
int inputPin = 2; // choose the input pin (for PIR sensor)
int inputPin2 = 1;
int pirState1 = LOW; // we start, assuming no motion detected
int pirState2 = LOW;
int val = 0; // variable for reading the pin status
int val2 = 0;
int pinSpeaker = 10; //Set up a speaker on a PWM pin (digital 9, 10, or 11)
void setup() {
pinMode(ledPin1, OUTPUT); // declare LED as output
pinMode(ledPin2, OUTPUT); // declare LED as output
pinMode(ledPin3, OUTPUT);
pinMode(inputPin, INPUT); // declare sensor 1 as input
pinMode(inputPin2, INPUT); // declare sensor 2 as input
// pinMode(pinSpeaker, OUTPUT);
Serial.begin(9600);
}
void loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin1, HIGH); // turn LED ON
delay (1500);
if (pirState1 == LOW) {
// we have just turned on
Serial.println("Motion1 detected!");
// We only want to print on the output change, not state
pirState1 = HIGH;
}
delay (1500);
// check sensor 2 after delay
val2 = digitalRead(inputPin2);
if (val2 == HIGH){
digitalWrite(ledPin2, LOW);
delay(1500);
digitalWrite(ledPin3,HIGH);
//playTone(300, 160);
delay(1500);
if (pirState2 == LOW) {
// we have just turned on
Serial.println("Motion1 from sensor 2 detected!");
// We only want to print on the output change, not state
pirState2 = HIGH;
}
}
if(val2 == LOW){
digitalWrite(ledPin2, HIGH);
//playTone(300, 160);
delay(1500);
digitalWrite(ledPin3,LOW);
delay(1500);
}
} else {
digitalWrite(ledPin1, LOW); // turn LED OFF
delay (1500);
digitalWrite(ledPin2, LOW); // may be already
//playTone(0, 0);
delay(1500);
digitalWrite(ledPin3, LOW); // turn LED OFF
delay (1500);
if (pirState1 == HIGH){
// we have just turned of
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState1 = LOW;
}
if (pirState2 == HIGH){
// we have just turned of
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState2 = LOW;
}
}
}
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
`
Change inputPin2 from 1 to 3 for example. Just don't use the pins 0 or 1 (those assigned for Tx and Rx), hope this works.

How to parallelize Sudoku solver using Grand Central Dispatch?

As a programming exercise, I just finished writing a Sudoku solver that uses the backtracking algorithm (see Wikipedia for a simple example written in C).
To take this a step further, I would like to use Snow Leopard's GCD to parallelize this so that it runs on all of my machine's cores. Can someone give me pointers on how I should go about doing this and what code changes I should make? Thanks!
Matt
Please let me know if you end up using it. It is run of the mill ANSI C, so should run on everything. See other post for usage.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
short sudoku[9][9];
unsigned long long cubeSolutions=0;
void* cubeValues[10];
const unsigned char oneLookup[64] = {0x8b, 0x80, 0, 0x80, 0, 0, 0, 0x80, 0, 0,0,0,0,0,0, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ifOne(int val) {
if ( oneLookup[(val-1) >> 3] & (1 << ((val-1) & 0x7)) )
return val;
return 0;
}
void init_sudoku() {
int i,j;
for (i=0; i<9; i++)
for (j=0; j<9; j++)
sudoku[i][j]=0x1ff;
}
void set_sudoku( char* initialValues) {
int i;
if ( strlen (initialValues) != 81 ) {
printf("Error: inputString should have length=81, length is %2.2d\n", strlen(initialValues) );
exit (-12);
}
for (i=0; i < 81; i++)
if ((initialValues[i] > 0x30) && (initialValues[i] <= 0x3a))
sudoku[i/9][i%9] = 1 << (initialValues[i] - 0x31) ;
}
void print_sudoku ( int style ) {
int i, j, k;
for (i=0; i < 9; i++) {
for (j=0; j < 9; j++) {
if ( ifOne(sudoku[i][j]) || !style) {
for (k=0; k < 9; k++)
if (sudoku[i][j] & 1<<k)
printf("%d", k+1);
} else
printf("*");
if ( !((j+1)%3) )
printf("\t");
else
printf(",");
}
printf("\n");
if (!((i+1) % 3) )
printf("\n");
}
}
void print_HTML_sudoku () {
int i, j, k, l, m;
printf("<TABLE>\n");
for (i=0; i<3; i++) {
printf(" <TR>\n");
for (j=0; j<3; j++) {
printf(" <TD><TABLE>\n");
for (l=0; l<3; l++) { printf(" <TR>"); for (m=0; m<3; m++) { printf("<TD>"); for (k=0; k < 9; k++) { if (sudoku[i*3+l][j*3+m] & 1<<k)
printf("%d", k+1);
}
printf("</TD>");
}
printf("</TR>\n");
}
printf(" </TABLE></TD>\n");
}
printf(" </TR>\n");
}
printf("</TABLE>");
}
int doRow () {
int count=0, new_value, row_value, i, j;
for (i=0; i<9; i++) {
row_value=0x1ff;
for (j=0; j<9; j++)
row_value&=~ifOne(sudoku[i][j]);
for (j=0; j<9; j++) {
new_value=sudoku[i][j] & row_value;
if (new_value && (new_value != sudoku[i][j]) ) {
count++;
sudoku[i][j] = new_value;
}
}
}
return count;
}
int doCol () {
int count=0, new_value, col_value, i, j;
for (i=0; i<9; i++) {
col_value=0x1ff;
for (j=0; j<9; j++)
col_value&=~ifOne(sudoku[j][i]);
for (j=0; j<9; j++) {
new_value=sudoku[j][i] & col_value;
if (new_value && (new_value != sudoku[j][i]) ) {
count++;
sudoku[j][i] = new_value;
}
}
}
return count;
}
int doCube () {
int count=0, new_value, cube_value, i, j, l, m;
for (i=0; i<3; i++)
for (j=0; j<3; j++) {
cube_value=0x1ff;
for (l=0; l<3; l++)
for (m=0; m<3; m++)
cube_value&=~ifOne(sudoku[i*3+l][j*3+m]);
for (l=0; l<3; l++)
for (m=0; m<3; m++) {
new_value=sudoku[i*3+l][j*3+m] & cube_value;
if (new_value && (new_value != sudoku[i*3+l][j*3+m]) ) {
count++;
sudoku[i*3+l][j*3+m] = new_value;
}
}
}
return count;
}
#define FALSE -1
#define TRUE 1
#define INCOMPLETE 0
int validCube () {
int i, j, l, m, r, c;
int pigeon;
int solved=TRUE;
//check horizontal
for (i=0; i<9; i++) {
pigeon=0;
for (j=0; j<9; j++)
if (ifOne(sudoku[i][j])) {
if (pigeon & sudoku[i][j]) return FALSE;
pigeon |= sudoku[i][j];
} else {
solved=INCOMPLETE;
}
}
//check vertical
for (i=0; i<9; i++) {
pigeon=0;
for (j=0; j<9; j++)
if (ifOne(sudoku[j][i])) {
if (pigeon & sudoku[j][i]) return FALSE;
pigeon |= sudoku[j][i];
}
else {
solved=INCOMPLETE;
}
}
//check cube
for (i=0; i<3; i++)
for (j=0; j<3; j++) {
pigeon=0;
r=j*3; c=i*3;
for (l=0; l<3; l++)
for (m=0; m<3; m++)
if (ifOne(sudoku[r+l][c+m])) {
if (pigeon & sudoku[r+l][c+m]) return FALSE;
pigeon |= sudoku[r+l][c+m];
}
else {
solved=INCOMPLETE;
}
}
return solved;
}
int solveSudoku(int position ) {
int status, i, k;
short oldCube[9][9];
for (i=position; i < 81; i++) {
while ( doCube() + doRow() + doCol() );
status = validCube() ;
if ((status == TRUE) || (status == FALSE))
return status;
if ((status == INCOMPLETE) && !ifOne(sudoku[i/9][i%9]) ) {
memcpy( &oldCube, &sudoku, sizeof(short) * 81) ;
for (k=0; k < 9; k++) {
if ( sudoku[i/9][i%9] & (1<<k) ) {
sudoku[i/9][i%9] = 1 << k ;
if (solveSudoku(i+1) == TRUE ) {
/* return TRUE; */
/* Or look for entire set of solutions */
if (cubeSolutions < 10) {
cubeValues[cubeSolutions] = malloc ( sizeof(short) * 81 ) ;
memcpy( cubeValues[cubeSolutions], &sudoku, sizeof(short) * 81) ;
}
cubeSolutions++;
if ((cubeSolutions & 0x3ffff) == 0x3ffff ) {
printf ("cubeSolutions = %llx\n", cubeSolutions+1 );
}
//if ( cubeSolutions > 10 )
// return TRUE;
}
memcpy( &sudoku, &oldCube, sizeof(short) * 81) ;
}
if (k==8)
return FALSE;
}
}
}
return FALSE;
}
int main ( int argc, char** argv) {
int i;
if (argc != 2) {
printf("Error: number of arguments on command line is incorrect\n");
exit (-12);
}
init_sudoku();
set_sudoku(argv[1]);
printf("[----------------------- Input Data ------------------------]\n\n");
print_sudoku(1);
solveSudoku(0);
if ((validCube()==1) && !cubeSolutions) {
// If sudoku is effectively already solved, cubeSolutions will not be set
printf ("\n This is a trivial sudoku. \n\n");
print_sudoku(1);
}
if (!cubeSolutions && validCube()!=1)
printf("Not Solvable\n");
if (cubeSolutions > 1) {
if (cubeSolutions >= 10)
printf("10+ Solutions, returning first 10 (%lld) [%llx] \n", cubeSolutions, cubeSolutions);
else
printf("%llx Solutions. \n", cubeSolutions);
}
for (i=0; (i < cubeSolutions) && (i < 10); i++) {
memcpy ( &sudoku, cubeValues[i], sizeof(short) * 81 );
printf("[----------------------- Solution %2.2d ------------------------]\n\n", i+1);
print_sudoku(0);
//print_HTML_sudoku();
}
return 0;
}
For one, since backtracking is a depth-first search it is not directly parallelizable, since any newly computed result cannot be used be directly used by another thread. Instead, you must divide the problem early, i.e. thread #1 starts with the first combination for a node in the backtracking graph, and proceeds to search the rest of that subgraph. Thread #2 starts with the second possible combination at the first and so forth. In short, for n threads find the n possible combinations on the top level of the search space (do not "forward-track"), then assign these n starting points to n threads.
However I think the idea is fundamentally flawed: Many sudoku permutations are solved in a matter of a couple thousands of forward+backtracking steps, and are solved within milliseconds on a single thread. This is in fact so fast that even the small coordination required for a few threads (assume that n threads reduce computation time to 1/n of original time) on a multi-core/multi-CPU is not negligible compared to the total running time, thus it is not by any chance a more efficient solution.
Are you sure you want to do that? Like, what problem are you trying to solve? If you want to use all cores, use threads. If you want a fast sudoku solver, I can give you one I wrote, see output below. If you want to make work for yourself, go ahead and use GCD ;).
Update:
I don't think GCD is bad, it just isn't terribly relevant to the task of solving sudoku. GCD is a technology to tie GUI events to code. Essentially, GCD solves two problems, a Quirk in how the MacOS X updates windows, and, it provides an improved method (as compared to threads) of tying code to GUI events.
It doesn't apply to this problem because Sudoku can be solved significantly faster than a person can think (in my humble opinion). That being said, if your goal was to solve Sudoku faster, you would want to use threads, because you would want to directly use more than one processor.
[bear#bear scripts]$ time ./a.out ..1..4.......6.3.5...9.....8.....7.3.......285...7.6..3...8...6..92......4...1...
[----------------------- Input Data ------------------------]
*,*,1 *,*,4 *,*,*
*,*,* *,6,* 3,*,5
*,*,* 9,*,* *,*,*
8,*,* *,*,* 7,*,3
*,*,* *,*,* *,2,8
5,*,* *,7,* 6,*,*
3,*,* *,8,* *,*,6
*,*,9 2,*,* *,*,*
*,4,* *,*,1 *,*,*
[----------------------- Solution 01 ------------------------]
7,6,1 3,5,4 2,8,9
2,9,8 1,6,7 3,4,5
4,5,3 9,2,8 1,6,7
8,1,2 6,4,9 7,5,3
9,7,6 5,1,3 4,2,8
5,3,4 8,7,2 6,9,1
3,2,7 4,8,5 9,1,6
1,8,9 2,3,6 5,7,4
6,4,5 7,9,1 8,3,2
real 0m0.044s
user 0m0.041s
sys 0m0.001s

Resources